Skip to content

Instantly share code, notes, and snippets.

@natevw
Created July 4, 2022 22:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save natevw/79e04dba0cda6c87e19eb63a6a4986ba to your computer and use it in GitHub Desktop.
Save natevw/79e04dba0cda6c87e19eb63a6a4986ba to your computer and use it in GitHub Desktop.
Promise Limiter, somewhat similar to https://github.com/d3/d3-queue or https://github.com/natevw/fifolock but with async Promises instead of callbacks
/*
import Politer from "./this_gist.mjs";
let q = Politer(2),
politelyFetch = q.wrap(fetch);
Promise.all([
politelyFetch(req1),
politelyFetch(req2),
politelyFetch(req3),
politelyFetch(req4),
politelyFetch(req5),
]).then(/* … */);
*/
export default class PromiseLimiter {
constructor(n) {
this._max = n;
this._wip = 0;
this._q = [];
}
_proceedIfReady() {
if (this._q.length && this._wip < this._max) {
++this._wip;
let task = this._q.pop();
task.fn.apply(task.ctx, task.args)
.then(result => { task.resolve(result); })
.catch(error => { task.reject(error); })
.finally(() => {
--this._wip;
this._proceedIfReady();
});
}
}
wrap(fn) {
let scope = this;
return function () {
let task = {fn, ctx:this, args:arguments};
let asyncResult = new Promise((resolve, reject) => {
Object.assign(task, {resolve,reject});
});
scope._q.unshift(task);
scope._proceedIfReady();
return asyncResult;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment