Skip to content

Repository files navigation

@avensio/async-pool

npm versionnpm downloadsDocumentationGitHubLicense

Documentation · GitHub

Lightweight concurrency control for async work in Node.js and browsers. createPool(limit) lets you cap how many promises run at once, so you can overlap I/O-bound tasks without flooding the event loop.

Features

  • Deterministic FIFO scheduling backed by LinkedQueue from @avensio/shared
  • Strict parameter validation with helpful errors for bad limits or task factories
  • Graceful handling of rejections: failed tasks free their slot and the queue keeps draining
  • Works in modern Node.js runtimes and ships as an IIFE bundle for browsers and Workers
  • Zero dependencies beyond @avensio/shared, which pulls in no transitive packages

Installation

pnpm add @avensio/async-pool
# npm install @avensio/async-pool# yarn add @avensio/async-pool

Quick start

import{createPool}from'@avensio/async-pool'constpool=createPool(8)constitems=[...Array(32).keys()]constresults=awaitPromise.all(items.map((item)=>pool(async()=>fetchData(item))))console.log(results)

Concurrency ≠ parallelism: the pool multiplexes async work on the same thread; use worker threads for CPU-bound tasks.

API

SignatureDescription
createPool(limit: number): PoolRunnerValidates limit (positive integer) and returns a function pool<T>(task: () => Promise<T>): Promise<T> that queues tasks when limit in-flight jobs are running.

Behavior & errors

  • Passing 0, negative, or non-integer limits throws RangeError before any task runs.
  • If the task callback is not a function, the returned promise rejects with TypeError.
  • Synchronous exceptions inside the task reject immediately; async rejections bubble up unchanged.
  • After any task settles (fulfilled or rejected) the slot is freed and the next queued workload starts.

See the API reference for details on queue internals, typing, and error propagation diagrams.

Usage patterns

import{createPool}from'@avensio/async-pool'constpool=createPool(4)// 1. Fire-and-forget (log errors)urls.forEach((url)=>{voidpool(()=>fetch(url).catch((err)=>logError(url,err)))})// 2. Per-resource limits (e.g., DB vs HTTP)constdbPool=createPool(2)consthttpPool=createPool(6)awaitPromise.all([
...queries.map((q)=>dbPool(()=>dbClient.query(q))),
...requests.map((req)=>httpPool(()=>fetch(req)))])// 3. Dynamic limit adjustmentletlimit=4constpoolFactory=()=>createPool(limit)// rebuild pool when you need to tighten/loosen concurrency

More recipes (timeouts, cancellation, queue draining) live in the usage guide.

Performance & limitations

  • Ideal for I/O-heavy operations whose concurrency must be capped.
  • For CPU-bound loops prefer worker_threads, cluster, or job queues.
  • Monitor queue depth to implement backpressure (patterns in performance.md).
  • The scheduler is FIFO; if you need priority queues, wrap LinkedQueue with your own structure.

Development

CommandDescription
pnpm testRun Vitest (test/pool.test.ts) with coverage (coverage/).
pnpm lintESLint with auto-fix.
pnpm buildBundle ESM, CJS, and IIFE outputs via Vite and regenerate types.
pnpm docs:dev / docs:buildWork on the VitePress docs.
pnpm releaseTest + build + changelog via changelogen.

Clone the repo, pnpm install, and keep docs/tests in sync with code changes. See docs/development.md for the full workflow.

Links

About

Lightweight FIFO concurrency control for asynchronous JavaScript and TypeScript tasks. Limit in-flight promises, keep queues draining after failures, and run consistently in Node.js, browsers, and workers.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages