Promise-Queue
sb-promise-queue is a lightweight JavaScript/TypeScript utility library designed to manage and control the concurrency of asynchronous operations using a promise-based queue. Its current stable version is 2.1.1. It allows developers to specify a maximum number of promises that can run simultaneously, preventing resource exhaustion or rate-limiting issues. Key differentiators include its minimalistic and intuitive API, built-in TypeScript type definitions for enhanced developer experience, and clear methods such as `add`, `onIdle`, and `waitTillIdle` for effective task flow management. This library is particularly useful for scenarios requiring controlled execution of potentially resource-intensive async tasks, like API calls or data processing, ensuring stability and performance. While a specific release cadence is not explicitly stated, as a focused utility, updates are generally driven by bug fixes or minor enhancements rather than frequent feature additions.
Common errors
-
TypeError: PromiseQueue is not a constructor
cause Attempting to use `new PromiseQueue()` without correctly importing it from the module, or when the `require` call in a CommonJS context did not properly destructure the named export.fixEnsure you are using the correct ES module named import: `import { PromiseQueue } from 'sb-promise-queue';`. If in a CommonJS environment, use `const { PromiseQueue } = require('sb-promise-queue');`. -
UnhandledPromiseRejectionWarning: Unhandled promise rejection.
cause An asynchronous task (a promise) within a callback added to the queue rejected, and this rejection was not explicitly caught by a `.catch()` block or `try...catch` statement within that specific task's execution.fixModify the `async` callback passed to `queue.add()` to include error handling. For example: `queue.add(async () => { try { await someAsyncOp(); } catch (error) { console.error('Task failed:', error); } });` -
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'sb-promise-queue' imported from ...
cause The package `sb-promise-queue` is either not installed, or your project's module resolution settings (e.g., for ES modules vs. CommonJS) are incorrect.fixFirst, ensure the package is installed: `npm install sb-promise-queue`. If the error persists in an ES module environment (`"type": "module"` in `package.json`), verify your Node.js version supports ES modules or check for incorrect `tsconfig.json` module settings if using TypeScript.
Warnings
- gotcha Forgetting to `await queue.waitTillIdle()` will cause your script or subsequent logic to execute before all queued asynchronous tasks have completed, potentially leading to incomplete operations or race conditions.
- gotcha Tasks added to the queue via `add(callback)` execute the `callback` function. If the promise returned by `callback` rejects and this rejection is not handled internally within the callback, it will result in an unhandled promise rejection error that might not halt other tasks but will break your process if unhandled globally.
- gotcha The `concurrency` option limits the number of *currently running* promises, not the total number of tasks that can be added to the queue. Adding an extremely large number of tasks (e.g., millions) to a queue with very low concurrency can lead to high memory consumption as all tasks await their turn.
Install
-
npm install sb-promise-queue -
yarn add sb-promise-queue -
pnpm add sb-promise-queue
Imports
- PromiseQueue
const PromiseQueue = require('sb-promise-queue');import { PromiseQueue } from 'sb-promise-queue'; - Options
import { Options } from 'sb-promise-queue';import { type Options, PromiseQueue } from 'sb-promise-queue'; - PromiseQueue (CommonJS fallback)
const { PromiseQueue } = require('sb-promise-queue');
Quickstart
import { PromiseQueue } from 'sb-promise-queue';
async function runConcurrentTasks() {
const queue = new PromiseQueue({ concurrency: 3 }); // Allow 3 tasks to run concurrently
const taskCount = 10;
const results: string[] = [];
console.log(`Starting ${taskCount} tasks with concurrency ${queue.options.concurrency}...`);
for (let i = 1; i <= taskCount; i++) {
queue.add(async () => {
console.log(` [Task ${i}] Started.`);
// Simulate an async operation with varying duration
await new Promise(resolve => setTimeout(resolve, Math.random() * 1000 + 500));
const result = `Task ${i} completed.`;
console.log(` [Task ${i}] Finished.`);
results.push(result);
return result;
});
}
// Wait for all tasks in the queue to finish
await queue.waitTillIdle();
console.log('All tasks finished!');
console.log('Results:', results);
}
runConcurrentTasks();