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

Commit 6731ad0

Browse files
MichaelBuergemhevery
authored andcommitted
feat: make fetch() zone-aware without triggering extra requests or uncatchable errors. (#622)
* Instrument with probePromise() * De-instrument (probePromise). * Introduce helper function to wraps any function returning a promise, ensuring a ZoneAwarePromise is returned. Use it on fetch(). * Minor readability improvement. * No need to wrap result promise in ZoneAwarePromise after patching its constructor. * Remove promise prober from karma build conf. * Address linter issues. * Use const.
1 parent d6772e2 commit 6731ad0

File tree

1 file changed

+34
-26
lines changed

1 file changed

+34
-26
lines changed

Diff for: lib/zone.ts

+34-26
Original file line numberDiff line numberDiff line change
@@ -1325,38 +1325,46 @@ const Zone: ZoneType = (function(global: any) {
13251325
ZoneAwarePromise['race'] = ZoneAwarePromise.race;
13261326
ZoneAwarePromise['all'] = ZoneAwarePromise.all;
13271327

1328-
const NativePromise = global[__symbol__('Promise')] = global['Promise'];
1328+
const NativePromise = global[symbolPromise] = global['Promise'];
13291329
global['Promise'] = ZoneAwarePromise;
1330-
function patchThen(NativePromise) {
1331-
const NativePromiseProtototype = NativePromise.prototype;
1332-
const NativePromiseThen = NativePromiseProtototype[__symbol__('then')] =
1333-
NativePromiseProtototype.then;
1334-
NativePromiseProtototype.then = function(onResolve, onReject) {
1335-
const nativePromise = this;
1336-
return new ZoneAwarePromise((resolve, reject) => {
1337-
NativePromiseThen.call(nativePromise, resolve, reject);
1338-
})
1339-
.then(onResolve, onReject);
1330+
1331+
const symbolThenPatched = __symbol__('thenPatched');
1332+
1333+
function patchThen(Ctor) {
1334+
const proto = Ctor.prototype;
1335+
const originalThen = proto.then;
1336+
// Keep a reference to the original method.
1337+
proto[symbolThen] = originalThen;
1338+
1339+
Ctor.prototype.then = function(onResolve, onReject) {
1340+
const wrapped = new ZoneAwarePromise((resolve, reject) => {
1341+
originalThen.call(this, resolve, reject);
1342+
});
1343+
return wrapped.then(onResolve, onReject);
13401344
};
1345+
Ctor[symbolThenPatched] = true;
13411346
}
13421347

1343-
if (NativePromise) {
1344-
patchThen(NativePromise);
1345-
if (typeof global['fetch'] !== 'undefined') {
1346-
let fetchPromise: Promise<any>;
1347-
try {
1348-
// In MS Edge this throws
1349-
fetchPromise = global['fetch']();
1350-
} catch (error) {
1351-
// In Chrome this throws instead.
1352-
fetchPromise = global['fetch']('about:blank');
1348+
function zoneify(fn) {
1349+
return function() {
1350+
let resultPromise = fn.apply(this, arguments);
1351+
if (resultPromise instanceof ZoneAwarePromise) {
1352+
return resultPromise;
13531353
}
1354-
// ignore output to prevent error;
1355-
fetchPromise.then(() => null, () => null);
1356-
if (fetchPromise.constructor != NativePromise &&
1357-
fetchPromise.constructor != ZoneAwarePromise) {
1358-
patchThen(fetchPromise.constructor);
1354+
let Ctor = resultPromise.constructor;
1355+
if (!Ctor[symbolThenPatched]) {
1356+
patchThen(Ctor);
13591357
}
1358+
return resultPromise;
1359+
};
1360+
}
1361+
1362+
if (NativePromise) {
1363+
patchThen(NativePromise);
1364+
1365+
let fetch = global['fetch'];
1366+
if (typeof fetch == 'function') {
1367+
global['fetch'] = zoneify(fetch);
13601368
}
13611369
}
13621370

0 commit comments

Comments
 (0)