tab-yoinker/01-scraper-urls/concurrent-queue.js
2021-09-23 23:15:03 -05:00

49 lines
1.1 KiB
JavaScript

// Runs a limited number of promises at one time
class ConcurrentQueue {
constructor(consecutive) {
this.consecutive = consecutive;
this.queue = [];
this.current = 0;
this.drainListeners = [];
}
_checkQueue() {
if (this.current == 0 && this.queue.length == 0) {
for (let drainListener of this.drainListeners) {
drainListener();
}
this.drainListeners = [];
}
while (this.current < this.consecutive && this.queue.length > 0) {
let taskData = this.queue.shift();
this.current += 1;
(async () => {
try {
taskData.resolve(await taskData.task());
} catch (e) {
taskData.reject(e);
}
this.current -= 1;
this._checkQueue();
})();
}
}
// returns a promise that can be awaited to get the resolution or rejection of the task's execution
push(task) {
return new Promise((resolve, reject) => {
this.queue.push({ task, resolve, reject })
this._checkQueue();
});
}
async waitForDrain() {
return new Promise((resolve) => {
this.drainListeners.push(resolve);
this._checkQueue();
});
}
}
module.exports = ConcurrentQueue;