Skip to content

Instantly share code, notes, and snippets.

@besrabasant
Created July 19, 2023 04:57
Show Gist options
  • Save besrabasant/80cd2352d1bce4316f51201bbb645893 to your computer and use it in GitHub Desktop.
Save besrabasant/80cd2352d1bce4316f51201bbb645893 to your computer and use it in GitHub Desktop.
Utility script for queuing promises
/**
* requestAnimationFrame polyfill from Paul Irish
* http://paulirish.com/2011/requestanimationframe-for-smart-animating/
* MIT license
*/
var lastTime = 0,
vendors = ["ms", "moz", "webkit", "o"]
for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x] + "RequestAnimationFrame"]
window.cancelAnimationFrame =
window[vendors[x] + "CancelAnimationFrame"] ||
window[vendors[x] + "CancelRequestAnimationFrame"]
}
if (!window.requestAnimationFrame) {
// Polyfill for IE8-9, Android <= 4.3
window.requestAnimationFrame = function(fn) {
var currTime = +new Date(),
timeToCall = Math.max(0, 16 - (currTime - lastTime)),
id = setTimeout(function() {
fn(currTime + timeToCall)
}, timeToCall)
lastTime = currTime + timeToCall
return id
}
}
if (!window.cancelAnimationFrame) {
window.cancelAnimationFrame = function(id) {
clearTimeout(id)
}
}
const p = cb => new Promise((fulfill, reject) => cb(fulfill, reject))
export class PromiseQueue {
/** @type {Array<Function|requestAnimationFrame>} */
stack = []
/**
* @param {*} context
*/
constructor(context = undefined) {
this.context = context || undefined
this.clear()
}
/**
* @param {Function} fn
* @param {*} ctx
*/
add(fn, ctx = undefined) {
this.stack.push(fn.bind(ctx || this.context))
return this
}
/**
* @param {Function} fn
* @param {*} ctx
*/
addPromise(fn, ctx = undefined) {
this.stack.push(() => p(fn.bind(ctx || this.context)))
return this
}
run() {
return this.stack.reduce((prev, fn) => {
return prev.then(fn)
}, Promise.resolve())
}
clear() {
this.stack = []
}
}
export class RafPromiseQueue extends PromiseQueue {
/**
* @param {Function} fn
* @param {*} ctx
*/
add(fn, ctx = undefined) {
this.stack.push(() => requestAnimationFrame(fn.bind(ctx || this.context)))
return this
}
/**
* @param {Function} fn
* @param {*} ctx
*/
addPromise(fn, ctx = undefined) {
this.stack.push(() =>
p(done => requestAnimationFrame(() => fn.call(ctx, done)))
)
return this
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment