Skip to content

Commit ed36174

Browse files
authored
Merge pull request #67 from github/polyfill-with-resolvers
polyfill for Promise.withResolvers
2 parents 9c5fd7d + 3a29ef5 commit ed36174

File tree

3 files changed

+72
-0
lines changed

3 files changed

+72
-0
lines changed

src/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as clipboardItem from './clipboarditem.js'
22
import * as elementCheckVisibility from './element-checkvisibility.js'
33
import * as navigatorClipboard from './navigator-clipboard.js'
4+
import * as withResolvers from './promise-withResolvers.js'
45
import * as requestIdleCallback from './requestidlecallback.js'
56

67
let supportsModalPseudo = false
@@ -47,6 +48,7 @@ export const polyfills = {
4748
elementCheckVisibility,
4849
navigatorClipboard,
4950
requestIdleCallback,
51+
withResolvers,
5052
}
5153

5254
export function isSupported() {

src/promise-withResolvers.ts

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*#__PURE__*/
2+
export function withResolvers<T>(this: PromiseConstructor) {
3+
const out = {} as {
4+
promise: Promise<T>
5+
resolve: (value: T | PromiseLike<T>) => void
6+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
7+
reject: (reason?: any) => void
8+
}
9+
out.promise = new Promise<T>((resolve, reject) => {
10+
out.resolve = resolve
11+
out.reject = reject
12+
})
13+
return out
14+
}
15+
16+
/*#__PURE__*/
17+
export function isSupported(): boolean {
18+
return 'withResolvers' in Promise && typeof Promise.withResolvers === 'function'
19+
}
20+
21+
/*#__PURE__*/
22+
export function isPolyfilled(): boolean {
23+
return 'withResolvers' in Promise && Promise.withResolvers === withResolvers
24+
}
25+
26+
export function apply(): void {
27+
if (!isSupported()) {
28+
Object.assign(Promise, {withResolvers})
29+
}
30+
}

test/promise-withResolvers.js

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import {apply, isPolyfilled, isSupported, withResolvers} from '../lib/promise-withResolvers.js'
2+
3+
describe('withResolvers', () => {
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('resolves to first resolving value', async () => {
13+
const arg = withResolvers()
14+
expect(Object.keys(arg).sort()).to.eql(['promise', 'reject', 'resolve'])
15+
expect(arg).to.have.property('promise').to.be.a('promise')
16+
expect(arg).to.have.property('resolve').to.be.a('function')
17+
expect(arg).to.have.property('reject').to.be.a('function')
18+
19+
arg.resolve(1)
20+
expect(await arg.promise).to.be.eql(1)
21+
})
22+
23+
it('rejects to first rejecting reason', async () => {
24+
const arg = withResolvers()
25+
expect(Object.keys(arg).sort()).to.eql(['promise', 'reject', 'resolve'])
26+
expect(arg).to.have.property('promise').to.be.a('promise')
27+
expect(arg).to.have.property('resolve').to.be.a('function')
28+
expect(arg).to.have.property('reject').to.be.a('function')
29+
30+
const err = new Error('rejected')
31+
32+
try {
33+
arg.reject(err)
34+
await arg.promise
35+
expect.fail('should fail')
36+
} catch (e) {
37+
expect(e).to.be.eql(err)
38+
}
39+
})
40+
})

0 commit comments

Comments
 (0)