UNPKG

queue-cb

Version:

A scalable queue for parallel callbacks

52 lines (51 loc) 1.89 kB
import LinkedArray from './LinkedArray.js'; let Queue = class Queue { _callAwait() { if (this._state.awaitCalled || !this._state.awaitCallback) return; this._state.awaitCalled = true; return this._state.awaitCallback(this._state.error); } _flush() { this._state.flushing = true; while(!this._state.error && this._state.tasks.length && this._state.runningCount < this._state.parallelism){ this._state.runningCount++; this._state.tasks.shift()(this._callDefer); } this._state.flushing = false; if (this._state.error || !(this._state.tasks.length + this._state.runningCount)) { this._callAwait(); } } _callDefer(err) { this._state.runningCount--; if (err && !this._state.error) this._state.error = err; if (this._state.flushing) return; this._flush(); } defer(defer) { if (this._state.error) return; if (this._state.runningCount < this._state.parallelism) { this._state.runningCount++; defer(this._callDefer); } else this._state.tasks.push(defer); } await(callback) { if (this._state.awaitCallback) throw new Error(`Awaiting callback was added twice: ${callback}`); this._state.awaitCallback = callback; if (this._state.error || !(this._state.tasks.length + this._state.runningCount)) return this._callAwait(); } constructor(parallelism = Infinity){ this._state = { parallelism, tasks: new LinkedArray(), runningCount: 0, error: null, awaitCallback: null, awaitCalled: false, flushing: false }; this._callAwait = this._callAwait.bind(this); this._callDefer = this._callDefer.bind(this); } }; export { Queue as default };