tiny-async-pool
Run many promise-returning functions with a bounded concurrency limit using native async iterators.
Repository Health
Technical Analysis
tiny-async-pool runs a collection of promise-returning or async functions against an iterable of inputs while capping how many run at once. Built entirely on native ES async iterators, async functions, and Promises, it exposes asyncPool as an async generator that yields each result the moment its task settles, keeping the concurrency window full without extra dependencies.
It rejects as soon as any underlying task rejects, invokes the iterator function as eagerly as the concurrency limit allows, and streams results in completion order. The library is a few dozen lines of code, making it a minimal alternative to heavier concurrency utilities for rate-limited I/O like API calls or file operations.
What You Get
- An
asyncPool(concurrency, iterable, iteratorFn)async generator that yields results as tasks settle. - Strict concurrency bounding so no more than N tasks run at any moment.
- Fail-fast behavior that rejects immediately when any underlying task rejects.
- A zero-dependency implementation built on native async iterators, async functions, and Promises.
Common Use Cases
- Throttling batches of HTTP requests to stay within an API’s rate limit.
- Processing large lists of files or records with a bounded number of in-flight operations.
- Fanning out async work while limiting memory and connection pressure.
Under The Hood
Architecture - The library’s core lives in lib/es9.js, which implements asyncPool as an async generator: it maintains a set of executing promises, starts new tasks from the iterable while the set size is below the concurrency limit, and await Promise.race(...) on the executing set to yield the next settled result and free a slot. An es7.js variant provides a Promise-array fallback for older baselines. Tech Stack - Pure JavaScript targeting Node with native async iterators (ES2018), async/await, and Promises; the package ships an es9 main entry and has no runtime dependencies. Code Quality - The implementation is intentionally minimal and well commented, with a test/ suite validating ordering and concurrency behavior; the README documents the exact call sequence and completion semantics. API Design - A single function, asyncPool(poolLimit, array, iteratorFn), drives everything and is consumed with for await...of, so the mental model is small and idiomatic for modern JavaScript.