Skip to content

Commit 9b88cd3

Browse files
authored
add Promise.allSettled
1 parent 60d896d commit 9b88cd3

3 files changed

Lines changed: 55 additions & 1 deletion

File tree

src/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import * as cryptoRandomUUID from './crypto-randomuuid.js'
66
import * as elementReplaceChildren from './element-replacechildren.js'
77
import * as eventAbortSignal from './event-abortsignal.js'
88
import * as objectHasOwn from './object-hasown.js'
9+
import * as promiseAllSettled from './promise-allsettled.js'
910
import * as promiseAny from './promise-any.js'
1011
import * as requestIdleCallback from './requestidlecallback.js'
1112

@@ -32,7 +33,7 @@ const baseSupport =
3233
'flatMap' in Array.prototype &&
3334
'trimEnd' in String.prototype &&
3435
// ES2020
35-
'allSettled' in Promise &&
36+
//'allSettled' in Promise && // Polyfilled
3637
'matchAll' in String.prototype &&
3738
// ES2021
3839
'replaceAll' in String.prototype &&
@@ -51,6 +52,7 @@ const polyfills = [
5152
elementReplaceChildren,
5253
eventAbortSignal,
5354
objectHasOwn,
55+
promiseAllSettled,
5456
promiseAny,
5557
requestIdleCallback
5658
]

src/promise-allsettled.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
export function promiseAllSettled<T extends readonly unknown[] | []>(
2+
values: T
3+
): Promise<{-readonly [P in keyof T]: PromiseSettledResult<Awaited<T[P]>>}> {
4+
return Promise.all(
5+
values.map(p =>
6+
// eslint-disable-next-line github/no-then
7+
Promise.resolve(p).then(
8+
(value: unknown) => ({status: 'fulfilled', value}),
9+
(reason: unknown) => ({status: 'rejected', reason})
10+
)
11+
)
12+
) as unknown as Promise<{-readonly [P in keyof T]: PromiseSettledResult<Awaited<T[P]>>}>
13+
}
14+
15+
/*#__PURE__*/
16+
export function isSupported(): boolean {
17+
return 'allSettled' in Promise && typeof Promise.allSettled === 'function'
18+
}
19+
20+
/*#__PURE__*/
21+
export function isPolyfilled(): boolean {
22+
return Promise.all === promiseAllSettled
23+
}
24+
25+
export function apply(): void {
26+
if (!isSupported()) {
27+
Promise.allSettled = promiseAllSettled
28+
}
29+
}

test/promise-allsettled.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import {apply, isPolyfilled, isSupported, promiseAllSettled} from '../lib/promise-allsettled.js'
2+
3+
describe('Promise.allSettled', () => {
4+
it('has standard isSupported, isPolyfilled, apply API', () => {
5+
expect(isSupported).to.be.a('function')
6+
expect(isPolyfilled).to.be.a('function')
7+
expect(apply).to.be.a('function')
8+
expect(isSupported()).to.be.a('boolean')
9+
expect(isPolyfilled()).to.equal(false)
10+
})
11+
12+
it('returns list of Promise value/rejections', async () => {
13+
expect(
14+
// eslint-disable-next-line prefer-promise-reject-errors
15+
await promiseAllSettled([Promise.resolve(1), Promise.reject(2), Promise.resolve(3), Promise.reject(4)])
16+
).to.eql([
17+
{status: 'fulfilled', value: 1},
18+
{status: 'rejected', reason: 2},
19+
{status: 'fulfilled', value: 3},
20+
{status: 'rejected', reason: 4}
21+
])
22+
})
23+
})

0 commit comments

Comments
 (0)