UNPKG

@monstermann/fn

Version:

A utility library for TypeScript.

65 lines (63 loc) 1.49 kB
import { defer } from "./defer.js"; import { createQueue, dequeue, enqueue } from "./internals/queue.js"; //#region src/promise/queue.ts /** * `queue(options)` * * Creates a queue that limits concurrent execution of tasks. * * ```ts * const taskQueue = queue({ concurrency: 2 }); * const taskQueue2 = queue(2); // shorthand * * const results = await Promise.all([ * // At most 2 fetch calls are executed at any time * taskQueue.add(() => fetchData(1)), * taskQueue.add(() => fetchData(2)), * taskQueue.add(() => fetchData(3)), * ]); * * // Wait for queue to become idle */ function queue(options) { const concurrency = getConcurrency(options); const queue$1 = createQueue(); let idle; let running = 0; function flush() { while (running < concurrency) { const next = dequeue(queue$1); if (!next) break; running++; next(); } if (!queue$1.size && running === 0) { idle?.resolve(); idle = void 0; } } function done() { running--; flush(); } return { add(fn) { idle ??= defer(); const deferred = defer(); const result = deferred.promise.then(fn).finally(done); enqueue(queue$1, deferred.resolve); flush(); return result; }, idle() { return idle?.promise ?? Promise.resolve(); } }; } function getConcurrency(options) { const base = typeof options === "number" ? options : options.concurrency; if (!Number.isSafeInteger(base)) return Infinity; return Math.max(base, 1); } //#endregion export { queue };