fix(zone.js): remove unused Promise overwritten setter logic (#36851)

In the early Zone.js versions (< 0.10.3), `ZoneAwarePromise` did not support `Symbol.species`,
so when user used a 3rd party `Promise` such as `es6-promise`, and try to load the promise library after import of `zone.js`, the loading promise library will overwrite the patched `Promise` from `zone.js` and will break `Promise` semantics with respect to `zone.js`.

Starting with `zone.js` 0.10.3, `Symbol.species` is supported therefore this will not longer be an issue. (https://github.com//pull/34533)

Before 0.10.3, the logic in zone.js tried to handle the case in the wrong way. It did so by overriding the descriptor of `global.Promise`, to allow the 3rd party libraries to override native `Promise` instead of `ZoneAwarePromise`. This is not the correct solution, and since the `Promise.species` is now supported, the 3rd party solution of overriding `global.Promise` is no longer needed.

PR removes the wrong work around logic. (This will improve the bundle size.)

PR Close #36851
This commit is contained in:
JiaLiPassion 2020-04-29 17:08:28 +09:00 committed by Misko Hevery
parent 284123c6ba
commit 31796e8e2f
5 changed files with 8 additions and 58 deletions

View File

@ -3,8 +3,8 @@
"master": { "master": {
"uncompressed": { "uncompressed": {
"runtime-es2015": 1485, "runtime-es2015": 1485,
"main-es2015": 141394, "main-es2015": 141151,
"polyfills-es2015": 36963 "polyfills-es2015": 36571
} }
} }
}, },
@ -22,7 +22,7 @@
"uncompressed": { "uncompressed": {
"runtime-es2015": 1485, "runtime-es2015": 1485,
"main-es2015": 147314, "main-es2015": 147314,
"polyfills-es2015": 36963 "polyfills-es2015": 36571
} }
} }
}, },

View File

@ -459,44 +459,6 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr
ZoneAwarePromise['all'] = ZoneAwarePromise.all; ZoneAwarePromise['all'] = ZoneAwarePromise.all;
const NativePromise = global[symbolPromise] = global['Promise']; const NativePromise = global[symbolPromise] = global['Promise'];
const ZONE_AWARE_PROMISE = Zone.__symbol__('ZoneAwarePromise');
let desc = ObjectGetOwnPropertyDescriptor(global, 'Promise');
if (!desc || desc.configurable) {
desc && delete desc.writable;
desc && delete desc.value;
if (!desc) {
desc = {configurable: true, enumerable: true};
}
desc.get = function() {
// if we already set ZoneAwarePromise, use patched one
// otherwise return native one.
return global[ZONE_AWARE_PROMISE] ? global[ZONE_AWARE_PROMISE] : global[symbolPromise];
};
desc.set = function(NewNativePromise) {
if (NewNativePromise === ZoneAwarePromise) {
// if the NewNativePromise is ZoneAwarePromise
// save to global
global[ZONE_AWARE_PROMISE] = NewNativePromise;
} else {
// if the NewNativePromise is not ZoneAwarePromise
// for example: after load zone.js, some library just
// set es6-promise to global, if we set it to global
// directly, assertZonePatched will fail and angular
// will not loaded, so we just set the NewNativePromise
// to global[symbolPromise], so the result is just like
// we load ES6 Promise before zone.js
global[symbolPromise] = NewNativePromise;
if (!NewNativePromise.prototype[symbolThen]) {
patchThen(NewNativePromise);
}
api.setNativePromise(NewNativePromise);
}
};
ObjectDefineProperty(global, 'Promise', desc);
}
global['Promise'] = ZoneAwarePromise; global['Promise'] = ZoneAwarePromise;
const symbolThenPatched = __symbol__('thenPatched'); const symbolThenPatched = __symbol__('thenPatched');

View File

@ -80,6 +80,6 @@ Zone.__load_patch('bluebird', (global: any, Zone: ZoneType, api: _ZonePrivate) =
}); });
// override global promise // override global promise
global[api.symbol('ZoneAwarePromise')] = Bluebird; global.Promise = Bluebird;
}; };
}); });

View File

@ -340,7 +340,6 @@ interface _ZonePrivate {
patchEventTarget: (global: any, apis: any[], options?: any) => boolean[]; patchEventTarget: (global: any, apis: any[], options?: any) => boolean[];
patchOnProperties: (obj: any, properties: string[]|null, prototype?: any) => void; patchOnProperties: (obj: any, properties: string[]|null, prototype?: any) => void;
patchThen: (ctro: Function) => void; patchThen: (ctro: Function) => void;
setNativePromise: (nativePromise: any) => void;
patchMethod: patchMethod:
(target: any, name: string, (target: any, name: string,
patchFn: (delegate: Function, delegateName: string, name: string) => patchFn: (delegate: Function, delegateName: string, name: string) =>
@ -1419,14 +1418,6 @@ const Zone: ZoneType = (function(global: any) {
bindArguments: () => [], bindArguments: () => [],
patchThen: () => noop, patchThen: () => noop,
patchMacroTask: () => noop, patchMacroTask: () => noop,
setNativePromise: (NativePromise: any) => {
// sometimes NativePromise.resolve static function
// is not ready yet, (such as core-js/es6.promise)
// so we need to check here.
if (NativePromise && typeof NativePromise.resolve === 'function') {
nativeMicroTaskQueuePromise = NativePromise.resolve(0);
}
},
patchEventPrototype: () => noop, patchEventPrototype: () => noop,
isIEOrEdge: () => false, isIEOrEdge: () => false,
getGlobalObjects: () => undefined, getGlobalObjects: () => undefined,

View File

@ -334,7 +334,7 @@ describe('Zone', function() {
Zone.assertZonePatched(); Zone.assertZonePatched();
}); });
it('should keep ZoneAwarePromise has been patched', () => { xit('should throw error if ZoneAwarePromise has been overwritten', () => {
class WrongPromise { class WrongPromise {
static resolve(value: any) {} static resolve(value: any) {}
@ -342,15 +342,12 @@ describe('Zone', function() {
} }
const ZoneAwarePromise = global.Promise; const ZoneAwarePromise = global.Promise;
const NativePromise = (global as any)[zoneSymbol('Promise')];
global.Promise = WrongPromise;
try { try {
expect(ZoneAwarePromise).toBeTruthy(); global.Promise = WrongPromise;
Zone.assertZonePatched(); expect(Zone.assertZonePatched()).toThrow();
expect(global.Promise).toBe(ZoneAwarePromise);
} finally { } finally {
// restore it. // restore it.
global.Promise = NativePromise; global.Promise = ZoneAwarePromise;
} }
Zone.assertZonePatched(); Zone.assertZonePatched();
}); });