Skip to content

Commit 08b0c87

Browse files
JiaLiPassionalxhub
authored andcommitted
fix(zone.js): Promise.resolve(subPromise) should return subPromise (#53423)
In the original `Promise` impelmentation, zone.js follow the spec from https://promisesaplus.com/#point-51. ``` const p1 = Promise.resolve(1); const p2 = Promise.resolve(p1); p1 === p2; // false ``` in this case, `p2` should be the same status with `p1` but they are still different instances. And for some edge case. ``` class MyPromise extends Promise { constructor(sub) { super((res) => res(null)); this.sub = sub; } then(onFufilled, onRejected) { this.sub.then(onFufilled, onRejected); } } const p1 = new Promise(setTimeout(res), 100); const myP = new MyPromise(p1); const r = await myP; r === 1; // false ``` So in the above code, `myP` is not the same instance with `p1`, and since `myP` is resolved in constructor, so `await myP` will just pass without waiting for `p1`. And in the current `tc39` spec here https://tc39.es/ecma262/multipage/control-abstraction-objects.html#sec-promise-resolve `Promise.resolve(subP)` should return `subP`. ``` const p1 = Promise.resolve(1); const p2 = Promise.resolve(p1); p1 === p2; // true ``` So the above `MyPromise` can wait for the `p1` correctly. PR Close #53423
1 parent e3a6bf9 commit 08b0c87

7 files changed

Lines changed: 30 additions & 312 deletions

File tree

.github/workflows/ci.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,6 @@ jobs:
234234
# Install
235235
- run: yarn --cwd packages/zone.js install --frozen-lockfile --non-interactive
236236
# Run zone.js tools tests
237-
- run: yarn --cwd packages/zone.js promisetest
238237
- run: yarn --cwd packages/zone.js promisefinallytest
239238
- run: yarn --cwd packages/zone.js jest:test
240239
- run: yarn --cwd packages/zone.js jest:nodetest

packages/zone.js/README.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,5 @@ import 'zone.js/plugins/zone-patch-canvas';
134134
|`zone-patch-user-media.js`|patch for `UserMedia API`|
135135
|`zone-patch-message-port.js`|patch for `MessagePort API`|
136136

137-
## Promise A+ test passed
138-
[![Promises/A+ 1.1 compliant](https://promisesaplus.com/assets/logo-small.png)](https://promisesaplus.com/)
139-
140137
## License
141138
MIT

packages/zone.js/lib/common/promise.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,9 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr
292292
}
293293

294294
static resolve<R>(value: R): Promise<R> {
295+
if (value instanceof ZoneAwarePromise) {
296+
return value;
297+
}
295298
return resolvePromise(<ZoneAwarePromise<R>>new this(null as any), RESOLVED, value);
296299
}
297300

packages/zone.js/package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,13 @@
1919
"jest-environment-jsdom": "^29.0.3",
2020
"jest-environment-node": "^29.0.3",
2121
"mocha": "^10.2.0",
22-
"mock-require": "3.0.3",
23-
"promises-aplus-tests": "^2.1.2"
22+
"mock-require": "3.0.3"
2423
},
2524
"scripts": {
2625
"closuretest": "./scripts/closure/closure_compiler.sh",
2726
"electrontest": "cd test/extra && node electron.js",
2827
"jest:test": "jest --config ./test/jest/jest.config.js ./test/jest/jest.spec.js",
2928
"jest:nodetest": "jest --config ./test/jest/jest.node.config.js ./test/jest/jest.spec.js",
30-
"promisetest": "node ./test/promise/promise-test.mjs",
3129
"promisefinallytest": "mocha ./test/promise/promise.finally.spec.mjs"
3230
},
3331
"repository": {

packages/zone.js/test/common/Promise.spec.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {isNode, zoneSymbol} from '../../lib/common/utils';
9+
import {isNode} from '../../lib/common/utils';
1010
import {ifEnvSupports} from '../test-util';
1111

1212
declare const global: any;
@@ -76,6 +76,12 @@ describe(
7676
expect(new Promise(() => null) instanceof Promise).toBe(true);
7777
});
7878

79+
it('Promise.resolve(subPromise) should equal to subPromise', () => {
80+
const p1 = Promise.resolve(1);
81+
const p2 = Promise.resolve(p1);
82+
expect(p1).toBe(p2);
83+
});
84+
7985
xit('should ensure that Promise this is instanceof Promise', () => {
8086
expect(() => {
8187
Promise.call({} as any, () => null);
@@ -130,6 +136,23 @@ describe(
130136
expect(new MyPromise(() => {}).then(() => null) instanceof MyPromise).toBe(true);
131137
});
132138

139+
it('should allow subclassing with own then', (done: DoneFn) => {
140+
class MyPromise extends Promise<any> {
141+
constructor(private sub: Promise<any>) {
142+
super((resolve) => {resolve(null)});
143+
}
144+
145+
override then(onFulfilled: any, onRejected: any) {
146+
return this.sub.then(onFulfilled, onRejected);
147+
}
148+
}
149+
const p = Promise.resolve(1);
150+
new MyPromise(p).then((v: any) => {
151+
expect(v).toBe(1);
152+
done();
153+
}, () => done());
154+
});
155+
133156
it('Symbol.species should return ZoneAwarePromise', () => {
134157
const empty = function() {};
135158
const promise = Promise.resolve(1);

packages/zone.js/test/promise/promise-test.mjs

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)