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+ /**
10+ * patch nodejs async operations (timer, promise, net...) with
11+ * nodejs async_hooks
12+ */
13+ Zone . __load_patch ( 'node_async_hooks_promise' , ( global : any , Zone : ZoneType , api : _ZonePrivate ) => {
14+ let async_hooks ;
15+ try {
16+ async_hooks = require ( 'async_hooks' ) ;
17+ } catch ( err ) {
18+ print ( err . message ) ;
19+ return ;
20+ }
21+
22+ const PROMISE_PROVIDER = 'PROMISE' ;
23+ const noop = function ( ) { } ;
24+
25+ const idPromise : { [ key : number ] : any } = { } ;
26+
27+ function print ( ...args : string [ ] ) {
28+ if ( ! args ) {
29+ return ;
30+ }
31+ ( process as any ) . _rawDebug ( args . join ( ' ' ) ) ;
32+ }
33+
34+ function init ( id : number , provider : string , triggerId : number , parentHandle : any ) {
35+ if ( provider === PROMISE_PROVIDER ) {
36+ if ( ! parentHandle ) {
37+ print ( 'no parenthandle' ) ;
38+ return ;
39+ }
40+ const promise = parentHandle . promise ;
41+ const originalThen = promise . then ;
42+
43+ const zone = Zone . current ;
44+ if ( zone . name === 'promise' ) {
45+ print ( 'init promise' , id . toString ( ) ) ;
46+ }
47+ if ( ! zone . parent ) {
48+ print ( 'root zone' ) ;
49+ return ;
50+ }
51+ const currentAsyncContext : any = { } ;
52+ currentAsyncContext . id = id ;
53+ currentAsyncContext . zone = zone ;
54+ idPromise [ id ] = currentAsyncContext ;
55+ promise . then = function ( onResolve : any , onReject : any ) {
56+ const wrapped = new Promise ( ( resolve , reject ) => {
57+ originalThen . call ( this , resolve , reject ) ;
58+ } ) ;
59+ if ( zone ) {
60+ ( wrapped as any ) . zone = zone ;
61+ }
62+ return zone . run ( ( ) => {
63+ return wrapped . then ( onResolve , onReject ) ;
64+ } ) ;
65+ } ;
66+ }
67+ }
68+
69+ function before ( id : number ) {
70+ const currentAsyncContext = idPromise [ id ] ;
71+ if ( currentAsyncContext ) {
72+ print ( 'before ' + id , currentAsyncContext . zone . name ) ;
73+ api . setAsyncContext ( currentAsyncContext ) ;
74+ }
75+ }
76+
77+ function after ( id : number ) {
78+ const currentAsyncContext = idPromise [ id ] ;
79+ if ( currentAsyncContext ) {
80+ print ( 'after ' + id , currentAsyncContext . zone . name ) ;
81+ idPromise [ id ] = null ;
82+ api . setAsyncContext ( null ) ;
83+ }
84+ }
85+
86+ function destroy ( id : number ) {
87+ print ( 'destroy ' + id ) ;
88+ }
89+
90+ async_hooks . createHook ( { init, before, after, destroy} ) . enable ( ) ;
91+ } ) ;
0 commit comments