What is tiny-async-pool?
The tiny-async-pool npm package is a lightweight utility for managing a pool of asynchronous tasks. It allows you to run a limited number of asynchronous operations concurrently, which can be useful for controlling resource usage and improving performance in scenarios where you have a large number of tasks to process.
What are tiny-async-pool's main functionalities?
Basic Usage
This example demonstrates the basic usage of tiny-async-pool. It runs a pool of asynchronous tasks with a concurrency limit of 2. The `timeout` function simulates an asynchronous operation that resolves after 1 second. The pool processes the array [1, 2, 3, 4, 5] with a concurrency of 2, meaning only 2 tasks will run at the same time.
const asyncPool = require('tiny-async-pool');
const timeout = (i) => new Promise(resolve => setTimeout(() => resolve(i), 1000));
(async () => {
const results = await asyncPool(2, [1, 2, 3, 4, 5], timeout);
console.log(results); // [1, 2, 3, 4, 5]
})();
Handling Errors
This example shows how to handle errors in tiny-async-pool. The `faultyTask` function simulates an asynchronous operation that rejects with an error for even numbers. The pool processes the array [1, 2, 3, 4, 5] with a concurrency of 2. If any task fails, the error is caught and logged.
const asyncPool = require('tiny-async-pool');
const faultyTask = (i) => new Promise((resolve, reject) => {
if (i % 2 === 0) reject(new Error(`Error on ${i}`));
else resolve(i);
});
(async () => {
try {
const results = await asyncPool(2, [1, 2, 3, 4, 5], faultyTask);
console.log(results);
} catch (error) {
console.error(error); // Error on 2
}
})();
Other packages similar to tiny-async-pool
p-limit
The p-limit package provides a similar functionality by limiting the number of concurrent promises. It allows you to create a limit function that can be used to wrap your asynchronous tasks, ensuring that only a specified number of them run concurrently. Compared to tiny-async-pool, p-limit offers more flexibility in how you structure your code but requires more boilerplate.
async
The async package is a comprehensive utility module that provides various functions for working with asynchronous JavaScript. It includes methods for parallel and series execution, queue management, and more. While it offers more features than tiny-async-pool, it is also larger and more complex, which might be overkill for simple concurrency control.
promise-pool
The promise-pool package is another utility for managing a pool of promises with a concurrency limit. It is similar to tiny-async-pool in terms of functionality but offers additional features like progress tracking and cancellation. It is a good alternative if you need more advanced control over your asynchronous tasks.
asyncPool
Why?
The goal of this library is to use native async iterator (ES9), native async functions and native Promise to implement the concurrency behavior (look our source code).
If you need ES6 as baseline, please use our version 1.x.
What?
asyncPool
runs multiple promise-returning & async functions in a limited concurrency pool. It rejects immediately as soon as one of the promises rejects. It calls the iterator function as soon as possible (under concurrency limit). It returns an async iterator that yields as soon as a promise completes (under concurrency limit). For example:
const timeout = ms => new Promise(resolve => setTimeout(() => resolve(ms), ms));
for await (const ms of asyncPool(2, [1000, 5000, 3000, 2000], timeout)) {
console.log(ms);
}
Usage
$ npm install tiny-async-pool
import asyncPool from "tiny-async-pool";
ES9 for await...of
for await (const value of asyncPool(concurrency, iterable, iteratorFn)) {
...
}
Migrating from 1.x
The main difference: 1.x API waits until all of the promises completes, then all results are returned (example below). The new API (thanks to async iteration) let each result be returned as soon as it completes (example above).
You may prefer to keep the 1.x style syntax, instead of the for await
iteration method in 2.x. Define a function like below to wrap asyncPool
, and this function will allow you to upgrade to 2.x without having to heavily modify your existing code.
async function asyncPoolAll(...args) {
const results = [];
for await (const result of asyncPool(...args)) {
results.push(result);
}
return results;
}
const results = await asyncPoolAll(concurrency, iterable, iteratorFn);
return asyncPoolAll(2, [1000, 5000, 3000, 2000], timeout).then(results => {...});
API
asyncPool(concurrency, iterable, iteratorFn)
Runs multiple promise-returning & async functions in a limited concurrency pool. It rejects immediately as soon as one of the promises rejects. It calls the iterator function as soon as possible (under concurrency limit). It returns an async iterator that yields as soon as a promise completes (under concurrency limit).
concurrency
The concurrency limit number (>= 1).
iterable
An input iterable object, such as String
, Array
, TypedArray
, Map
, and Set
.
iteratorFn
Iterator function that takes two arguments: the value of each iteration and the iterable object itself. The iterator function should either return a promise or be an async function.
License
MIT © Rafael Xavier de Souza