Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
tiny-async-pool
Advanced tools
Run multiple promise-returning & async functions with limited concurrency using native ES9
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.
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
}
})();
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.
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.
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.
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.
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);
}
// Call iterator timeout(1000)
// Call iterator timeout(5000)
// Concurrency limit of 2 reached, wait for the quicker one to complete...
// 1000 finishes
// for await...of outputs "1000"
// Call iterator timeout(3000)
// Concurrency limit of 2 reached, wait for the quicker one to complete...
// 3000 finishes
// for await...of outputs "3000"
// Call iterator timeout(2000)
// Itaration is complete, wait until running ones complete...
// 5000 finishes
// for await...of outputs "5000"
// 2000 finishes
// for await...of outputs "2000"
$ npm install tiny-async-pool
import asyncPool from "tiny-async-pool";
for await (const value of asyncPool(concurrency, iterable, iteratorFn)) {
...
}
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;
}
// ES7 API style available on our previous 1.x version
const results = await asyncPoolAll(concurrency, iterable, iteratorFn);
// ES6 API style available on our previous 1.x version
return asyncPoolAll(2, [1000, 5000, 3000, 2000], timeout).then(results => {...});
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).
The concurrency limit number (>= 1).
An input iterable object, such as String
, Array
, TypedArray
, Map
, and Set
.
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.
MIT © Rafael Xavier de Souza
FAQs
Run multiple promise-returning & async functions with limited concurrency using native ES9
The npm package tiny-async-pool receives a total of 1,270,936 weekly downloads. As such, tiny-async-pool popularity was classified as popular.
We found that tiny-async-pool demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.