| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- /**
- * @license
- * Copyright Google Inc. All Rights Reserved.
- *
- * Use of this source code is governed by an MIT-style license that can be
- * found in the LICENSE file at https://angular.io/license
- */
- /**
- * @fileoverview
- * @suppress {missingRequire}
- */
- Zone.__load_patch('fetch', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
- interface FetchTaskData extends TaskData {
- fetchArgs?: any[];
- }
- let fetch = global['fetch'];
- if (typeof fetch !== 'function') {
- return;
- }
- const originalFetch = global[api.symbol('fetch')];
- if (originalFetch) {
- // restore unpatched fetch first
- fetch = originalFetch;
- }
- const ZoneAwarePromise = global.Promise;
- const symbolThenPatched = api.symbol('thenPatched');
- const fetchTaskScheduling = api.symbol('fetchTaskScheduling');
- const fetchTaskAborting = api.symbol('fetchTaskAborting');
- const OriginalAbortController = global['AbortController'];
- const supportAbort = typeof OriginalAbortController === 'function';
- let abortNative: Function|null = null;
- if (supportAbort) {
- global['AbortController'] = function() {
- const abortController = new OriginalAbortController();
- const signal = abortController.signal;
- signal.abortController = abortController;
- return abortController;
- };
- abortNative = api.patchMethod(
- OriginalAbortController.prototype, 'abort',
- (delegate: Function) => (self: any, args: any) => {
- if (self.task) {
- return self.task.zone.cancelTask(self.task);
- }
- return delegate.apply(self, args);
- });
- }
- const placeholder = function() {};
- global['fetch'] = function() {
- const args = Array.prototype.slice.call(arguments);
- const options = args.length > 1 ? args[1] : null;
- const signal = options && options.signal;
- return new Promise((res, rej) => {
- const task = Zone.current.scheduleMacroTask(
- 'fetch', placeholder, {fetchArgs: args} as FetchTaskData,
- () => {
- let fetchPromise;
- let zone = Zone.current;
- try {
- (zone as any)[fetchTaskScheduling] = true;
- fetchPromise = fetch.apply(this, args);
- } catch (error) {
- rej(error);
- return;
- } finally {
- (zone as any)[fetchTaskScheduling] = false;
- }
- if (!(fetchPromise instanceof ZoneAwarePromise)) {
- let ctor = fetchPromise.constructor;
- if (!ctor[symbolThenPatched]) {
- api.patchThen(ctor);
- }
- }
- fetchPromise.then(
- (resource: any) => {
- if (task.state !== 'notScheduled') {
- task.invoke();
- }
- res(resource);
- },
- (error: any) => {
- if (task.state !== 'notScheduled') {
- task.invoke();
- }
- rej(error);
- });
- },
- () => {
- if (!supportAbort) {
- rej('No AbortController supported, can not cancel fetch');
- return;
- }
- if (signal && signal.abortController && !signal.aborted &&
- typeof signal.abortController.abort === 'function' && abortNative) {
- try {
- (Zone.current as any)[fetchTaskAborting] = true;
- abortNative.call(signal.abortController);
- } finally {
- (Zone.current as any)[fetchTaskAborting] = false;
- }
- } else {
- rej('cancel fetch need a AbortController.signal');
- }
- });
- if (signal && signal.abortController) {
- signal.abortController.task = task;
- }
- });
- };
- });
|