1+ /**
2+ * @license
3+ * Copyright Google Inc. All Rights Reserved.
4+ *
5+ * Use of this source code is governed by an MIT-style license that can be
6+ * found in the LICENSE file at https://angular.io/license
7+ */
8+
9+ Zone . __load_patch ( 'fetch' , ( global : any , Zone : ZoneType , api : _ZonePrivate ) => {
10+ const fetch = global [ 'fetch' ] ;
11+ const ZoneAwarePromise = global . Promise ;
12+ const symbolThenPatched = api . symbol ( 'thenPatched' ) ;
13+ const fetchTaskScheduling = api . symbol ( 'fetchTaskScheduling' ) ;
14+ const fetchTaskAborting = api . symbol ( 'fetchTaskAborting' ) ;
15+ if ( typeof fetch !== 'function' ) {
16+ return ;
17+ }
18+ const OriginalAbortController = global [ 'AbortController' ] ;
19+ const supportAbort = typeof OriginalAbortController === 'function' ;
20+ let abortNative : Function | null = null ;
21+ if ( supportAbort ) {
22+ global [ 'AbortController' ] = function ( ) {
23+ const abortController = new OriginalAbortController ( ) ;
24+ const signal = abortController . signal ;
25+ signal . abortController = abortController ;
26+ return abortController ;
27+ } ;
28+ abortNative = api . patchMethod (
29+ OriginalAbortController . prototype , 'abort' ,
30+ ( delegate : Function ) => ( self : any , args : any ) => {
31+ if ( self . task ) {
32+ return self . task . zone . cancelTask ( self . task ) ;
33+ }
34+ return delegate . apply ( self , args ) ;
35+ } ) ;
36+ }
37+ const placeholder = function ( ) { } ;
38+ global [ 'fetch' ] = function ( ) {
39+ const args = Array . prototype . slice . call ( arguments ) ;
40+ const options = args . length > 1 ? args [ 1 ] : null ;
41+ const signal = options && options . signal ;
42+ return new Promise ( ( res , rej ) => {
43+ const task = Zone . current . scheduleMacroTask (
44+ 'fetch' , placeholder , args ,
45+ ( ) => {
46+ let fetchPromise ;
47+ let zone = Zone . current ;
48+ try {
49+ ( zone as any ) [ fetchTaskScheduling ] = true ;
50+ fetchPromise = fetch . apply ( this , args ) ;
51+ } catch ( error ) {
52+ rej ( error ) ;
53+ return ;
54+ } finally {
55+ ( zone as any ) [ fetchTaskScheduling ] = false ;
56+ }
57+
58+ if ( ! ( fetchPromise instanceof ZoneAwarePromise ) ) {
59+ let ctor = fetchPromise . constructor ;
60+ if ( ! ctor [ symbolThenPatched ] ) {
61+ api . patchThen ( ctor ) ;
62+ }
63+ }
64+ fetchPromise . then (
65+ ( resource : any ) => {
66+ if ( task . state !== 'notScheduled' ) {
67+ task . invoke ( ) ;
68+ }
69+ res ( resource ) ;
70+ } ,
71+ ( error : any ) => {
72+ if ( task . state !== 'notScheduled' ) {
73+ task . invoke ( ) ;
74+ }
75+ rej ( error ) ;
76+ } ) ;
77+ } ,
78+ ( ) => {
79+ if ( ! supportAbort ) {
80+ rej ( 'No AbortController supported, can not cancel fetch' ) ;
81+ return ;
82+ }
83+ if ( signal && signal . abortController && ! signal . aborted &&
84+ typeof signal . abortController . abort === 'function' && abortNative ) {
85+ try {
86+ ( Zone . current as any ) [ fetchTaskAborting ] = true ;
87+ abortNative . call ( signal . abortController ) ;
88+ } finally {
89+ ( Zone . current as any ) [ fetchTaskAborting ] = false ;
90+ }
91+ } else {
92+ rej ( 'cancel fetch need a AbortController.signal' ) ;
93+ }
94+ } ) ;
95+ if ( signal && signal . abortController ) {
96+ signal . abortController . task = task ;
97+ }
98+ } ) ;
99+ } ;
100+ } ) ;
0 commit comments