p-map
Advanced tools
Comparing version 5.3.0 to 5.4.0
@@ -21,2 +21,26 @@ export interface Options { | ||
readonly stopOnError?: boolean; | ||
/** | ||
You can abort the promises using [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController). | ||
**Requires Node.js 16 or later.* | ||
@example | ||
``` | ||
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. | ||
``` | ||
*/ | ||
readonly signal?: AbortSignal; | ||
} | ||
@@ -23,0 +47,0 @@ |
49
index.js
import AggregateError from 'aggregate-error'; | ||
/** | ||
An error to be thrown when the request is aborted by AbortController. | ||
DOMException is thrown instead of this Error when DOMException is available. | ||
*/ | ||
export class AbortError extends Error { | ||
constructor(message) { | ||
super(); | ||
this.name = 'AbortError'; | ||
this.message = message; | ||
} | ||
} | ||
/** | ||
TODO: Remove AbortError and just throw DOMException when targeting Node 18. | ||
*/ | ||
const getDOMException = errorMessage => globalThis.DOMException === undefined | ||
? new AbortError(errorMessage) | ||
: new DOMException(errorMessage); | ||
/** | ||
TODO: Remove below function and just 'reject(signal.reason)' when targeting Node 18. | ||
*/ | ||
const getAbortedReason = signal => { | ||
const reason = signal.reason === undefined | ||
? getDOMException('This operation was aborted.') | ||
: signal.reason; | ||
return reason instanceof Error ? reason : getDOMException(reason); | ||
}; | ||
export default async function pMap( | ||
@@ -8,6 +38,7 @@ iterable, | ||
concurrency = Number.POSITIVE_INFINITY, | ||
stopOnError = true | ||
} = {} | ||
stopOnError = true, | ||
signal, | ||
} = {}, | ||
) { | ||
return new Promise((resolve, reject_) => { // eslint-disable-line promise/param-names | ||
return new Promise((resolve, reject_) => { | ||
if (iterable[Symbol.iterator] === undefined && iterable[Symbol.asyncIterator] === undefined) { | ||
@@ -41,2 +72,12 @@ throw new TypeError(`Expected \`input\` to be either an \`Iterable\` or \`AsyncIterable\`, got (${typeof iterable})`); | ||
if (signal) { | ||
if (signal.aborted) { | ||
reject(getAbortedReason(signal)); | ||
} | ||
signal.addEventListener('abort', () => { | ||
reject(getAbortedReason(signal)); | ||
}); | ||
} | ||
const next = async () => { | ||
@@ -69,3 +110,3 @@ if (isResolved) { | ||
if (!skippedIndexesMap.size) { | ||
if (skippedIndexesMap.size === 0) { | ||
resolve(result); | ||
@@ -72,0 +113,0 @@ return; |
{ | ||
"name": "p-map", | ||
"version": "5.3.0", | ||
"version": "5.4.0", | ||
"description": "Map over promises concurrently", | ||
@@ -47,3 +47,3 @@ "license": "MIT", | ||
"devDependencies": { | ||
"ava": "^3.15.0", | ||
"ava": "^4.1.0", | ||
"delay": "^5.0.0", | ||
@@ -53,5 +53,5 @@ "in-range": "^3.0.0", | ||
"time-span": "^5.0.0", | ||
"tsd": "^0.14.0", | ||
"xo": "^0.38.2" | ||
"tsd": "^0.19.1", | ||
"xo": "^0.48.0" | ||
} | ||
} |
@@ -81,2 +81,26 @@ # p-map | ||
##### signal | ||
Type: [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) | ||
You can abort the promises using [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController). | ||
*Requires Node.js 16 or later.* | ||
```js | ||
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. | ||
``` | ||
### pMapSkip | ||
@@ -83,0 +107,0 @@ |
16688
260
150