Skip to content
This repository was archived by the owner on Feb 26, 2024. It is now read-only.

Commit dafad98

Browse files
committed
fix(promise): allow Promise subclassing
When loading es6-shim the es6-shim clovers Zone Promise because it does not allow subclassing. This change now supports subclassing and verifies that constructor throws if invoked on non-Promise subclass. This change now allows es6-shim to be loaded after Zone.js
1 parent 6df5f93 commit dafad98

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

lib/zone.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,9 @@ const Zone: ZoneType = (function(global: any) {
10601060
constructor(executor: (resolve : (value?: R | Thenable<R>) => void,
10611061
reject: (error?: any) => void) => void) {
10621062
const promise: ZoneAwarePromise<R> = this;
1063+
if (!(promise instanceof ZoneAwarePromise)) {
1064+
throw new Error('Must be an instanceof Promise.');
1065+
}
10631066
promise[symbolState] = UNRESOLVED;
10641067
promise[symbolValue] = []; // queue;
10651068
try {
@@ -1072,7 +1075,7 @@ const Zone: ZoneType = (function(global: any) {
10721075
then<R, U>(onFulfilled?: (value: R) => U | Thenable<U>,
10731076
onRejected?: (error: any) => U | Thenable<U>): Promise<R>
10741077
{
1075-
const chainPromise: Promise<R> = new ZoneAwarePromise(null);
1078+
const chainPromise: Promise<R> = new (this.constructor as typeof ZoneAwarePromise)(null);
10761079
const zone = Zone.current;
10771080
if (this[symbolState] == UNRESOLVED ) {
10781081
(<any[]>this[symbolValue]).push(zone, chainPromise, onFulfilled, onRejected);

test/common/Promise.spec.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,22 @@ describe('Promise', ifEnvSupports('Promise', function () {
4545
it ('should make sure that new Promise is instance of Promise', () => {
4646
expect(Promise.resolve(123) instanceof Promise).toBe(true);
4747
expect(new Promise(() => null) instanceof Promise).toBe(true);
48-
})
48+
});
49+
50+
it('should ensure that Promise this is instanceof Promise', () => {
51+
expect(() => {
52+
Promise.call({}, null);
53+
}).toThrowError('Must be an instanceof Promise.');
54+
});
55+
56+
it('should allow subclassing', () => {
57+
class MyPromise extends Promise<any> {
58+
constructor(fn: any) {
59+
super(fn);
60+
}
61+
}
62+
expect(new MyPromise(null).then(() => null) instanceof MyPromise).toBe(true);
63+
});
4964

5065
it('should intercept scheduling of resolution and then', (done) => {
5166
pZone.run(() => {

0 commit comments

Comments
 (0)