Install p-map via npm
mainInstall the p-map package using npm to enable concurrent mapping over promises.
npm install p-maprepository·main·Indexed 23 days ago
https://github.com/sindresorhus/p-mapA utility for mapping over promises or iterables concurrently. Version 7.0.6 provides fine-grained control over concurrency, error handling, and backpressure. It includes pMap for returning a Promise that resolves to an Array, pMapIterable for streaming results via an async iterable, and pMapSkip for excluding specific elements from the final results.
Install the p-map package using npm to enable concurrent mapping over promises.
npm install p-mapWhen using pMap or pMapIterable, you can provide an options object to control execution behavior:
concurrency (number): The number of concurrently pending promises returned by mapper. Defaults to Infinity. Minimum is 1.stopOnError (boolean, pMap only): When true (default), the first mapper rejection will be rejected back to the consumer. When false, it waits for all promises to settle and rejects with an AggregateError containing all errors.signal (AbortSignal, pMap only): Allows aborting the promises using an AbortController.backpressure (number, pMapIterable only): The maximum number of promises returned by mapper that have resolved but not yet been collected by the consumer. Defaults to options.concurrency.// Example using signal to abort
import pMap from 'p-map';
import delay from 'delay';
const abortController = new AbortController();
setTimeout(() => {
abortController.abort();
}, 500);
const mapper = async value => value;
await pMap([delay(1000), delay(1000)], mapper, {signal: abortController.signal});
// Throws AbortError (DOMException) after 500 ms.To limit how often the mapper function is invoked (rate limiting), compose pMap with a rate limiter like p-throttle.
import pThrottle from 'p-throttle';
import pMap from 'p-map';
const throttle = pThrottle({
limit: 1,
interval: 1000,
strict: true,
});
const result = await pMap(input, throttle(mapper), {concurrency: 2});If you want to exclude certain elements from the final result array, return pMapSkip from your mapper function. This is useful for filtering results during the mapping process without changing the input array.
import pMap, {pMapSkip} from 'p-map';
import got from 'got';
const sites = [
getWebsiteFromUsername('sindresorhus'), //=> Promise
'https://avajs.dev',
'https://example.invalid',
'https://github.com'
];
const mapper = async site => {
try {
const {requestUrl} = await got.head(site);
return requestUrl;
} catch {
return pMapSkip;
}
};
const result = await pMap(sites, mapper, {concurrency: 2});
console.log(result);
//=> ['https://sindresorhus.com/', 'https://avajs.dev/', 'https://github.com/']Use pMap(input, mapper, options?) to run promise-returning or async functions multiple times with different inputs concurrently. Unlike Promise.all(), you can control the concurrency level and decide how to handle errors. It returns a Promise that resolves to an Array of the fulfilled values in the original input order.
import pMap from 'p-map';
import got from 'got';
const sites = [
getWebsiteFromUsername('sindresorhus'), //=> Promise
'https://avajs.dev',
'https://github.com'
];
const mapper = async site => {
const {requestUrl} = await got.head(site);
return requestUrl;
};
const result = await pMap(sites, mapper, {concurrency: 2});
console.log(result);
//=> ['https://sindresorhus.com/', 'https://avajs.dev/', 'https://github.com/']Use pMapIterable(input, mapper, options?) to return an async iterable that streams each return value from the mapper in order. This is useful for processing large datasets where you want to limit concurrency and manage backpressure.
import {pMapIterable} from 'p-map';
// Multiple posts are fetched concurrently, with limited concurrency and backpressure
for await (const post of pMapIterable(postIds, getPostMetadata, {concurrency: 8})) {
console.log(post);
};When using pMapIterable, you can provide IterableOptions to control execution and backpressure:
concurrency: The number of concurrently pending promises. Defaults to options.concurrency.backpressure: The maximum number of promises returned by mapper that have resolved but not yet been collected by the consumer. This limits calls to mapper to prevent overwhelming the consumer (e.g., if the consumer is saving results to a database slower than the mapper produces them).Use pMapIterable when you want to process results as they become available via an async iterable. This is ideal for streaming data (e.g., reading lines from a stream or a remote queue) where you want to consume results one by one without waiting for the entire collection to be processed.
import {pMapIterable} from 'p-map';
// Multiple posts are fetched concurrently, with limited concurrency and backpressure
for await (const post of pMapIterable(postIds, getPostMetadata, {concurrency: 8})) {
console.log(post);
};If you want to exclude certain items from the final result array (when using pMap) or the resulting async iterable (when using pMapIterable), return pMapSkip from your mapper function. This is useful for handling errors or filtering data during the mapping process.
import pMap, {pMapSkip} from 'p-map';
import got from 'got';
const sites = [
getWebsiteFromUsername('sindresorhus'), //=> Promise
'https://avajs.dev',
'https://example.invalid',
];
const mapper = async site => {
try {
const {requestUrl} = await got.head(site);
return requestUrl;
} catch {
return pMapSkip;
}
};
const result = await pMap(sites, mapper, {concurrency: 2});
console.log(result);
//=> ['https://sindresorhus.com/', 'https://avajs.dev/']The pMap function maps an Iterable or AsyncIterable to an array of results using a mapper function. It supports concurrency limiting and can be configured to stop on error or collect errors into an AggregateError.
Parameters:
iterable: An Iterable or AsyncIterable to map.mapper: A function that receives (element, index) and returns a promise or value.options (optional):concurrency: The maximum number of concurrent executions. Defaults to Number.POSITIVE_INFINITY.stopOnError: If true (default), the promise rejects immediately when the mapper throws. If false, errors are collected and thrown as an AggregateError once the iteration is complete.signal: An AbortSignal to cancel the operation.Use pMap to iterate over a synchronous or asynchronous iterable concurrently. It executes a mapper function for each element and returns a Promise that resolves to an Array of the results in the original order. This is useful for limiting concurrency when performing asynchronous tasks like HTTP requests.
import pMap from 'p-map';
import got from 'got';
const sites = [
getWebsiteFromUsername('sindresorhus'), //=> Promise
'https://avajs.dev',
'https://github.com'
];
const mapper = async site => {
const {requestUrl} = await got.head(site);
return requestUrl;
};
const result = await pMap(sites, mapper, {concurrency: 2});
console.log(result);
//=> ['https://sindresorhus.com/', 'https://avajs.dev/', 'https://github.com/']The pMapIterable function returns an AsyncIterable that maps an input iterable using a mapper function. This is useful for processing large streams of data where you want to control how many items are being processed at once and how many are buffered.
Parameters:
iterable: An Iterable or AsyncIterable to map.mapper: A function that receives (element, index) and returns a promise or value.options (optional):concurrency: The maximum number of concurrent executions. Defaults to Number.POSITIVE_INFINITY.backpressure: The maximum number of pending promises allowed in the buffer. Must be greater than or equal to concurrency. Defaults to concurrency.Behavior:
pMapSkip, that value is omitted from the yielded results.