Skip to content

Instantly share code, notes, and snippets.

@scwood
Last active April 19, 2022 19:04
Show Gist options
  • Select an option

  • Save scwood/1acf78276425e82da3eb9d6033ee49bc to your computer and use it in GitHub Desktop.

Select an option

Save scwood/1acf78276425e82da3eb9d6033ee49bc to your computer and use it in GitHub Desktop.
JavaScript Promise Queue
class PromiseQueue {
constructor({concurrency = 1} = {}) {
this.concurrency = concurrency;
this.queue = [];
this.pendingPromises = 0;
this.push = this.push.bind(this);
this._dequeue = this._dequeue.bind(this);
}
push(promiseGenerator) {
return new Promise((resolve, reject) => {
this.queue.push({promiseGenerator, resolve, reject});
this._dequeue();
});
}
_dequeue() {
if (
this.queue.length === 0 ||
this.pendingPromises >= this.concurrency
) {
return;
}
this.pendingPromises++;
const {promiseGenerator, resolve, reject} = this.queue.shift();
promiseGenerator()
.then(resolve)
.catch(reject)
.finally(() => {
this.pendingPromises--;
this._dequeue();
});
}
}
// Example
function somethingAsync() {
return new Promise((resolve, reject) => {
console.log('starting...');
setTimeout(() => {
console.log('...finishing');
resolve('tada!');
}, 1000);
})
}
let queue = new PromiseQueue();
queue.push(somethingAsync);
queue.push(somethingAsync);
// starting...
// ...finishing
// starting...
// ...finishing
queue = new PromiseQueue({concurrency: 2});
queue.push(somethingAsync);
queue.push(somethingAsync);
queue.push(somethingAsync);
// starting...
// starting...
// ...finishing
// ...finishing
// starting...
// ...finishing
queue.push(somethingAsync)
.then(result => console.log(result));
// starting...
// ...finishing
// tada!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment