11'use strict' ;
22
3- const { FunctionPrototype, Reflect } = primordials ;
3+ const { FunctionPrototype } = primordials ;
44
55const {
66 // For easy access to the nextTick state in the C++ land,
@@ -62,25 +62,24 @@ function processTicksAndRejections() {
6262 let tock ;
6363 do {
6464 while ( tock = queue . shift ( ) ) {
65- const asyncId = tock [ async_id_symbol ] ;
66- emitBefore ( asyncId , tock [ trigger_async_id_symbol ] ) ;
67- // emitDestroy() places the async_id_symbol into an asynchronous queue
68- // that calls the destroy callback in the future. It's called before
69- // calling tock.callback so destroy will be called even if the callback
70- // throws an exception that is handled by 'uncaughtException' or a
71- // domain.
72- // TODO(trevnorris): This is a bit of a hack. It relies on the fact
73- // that nextTick() doesn't allow the event loop to proceed, but if
74- // any async hooks are enabled during the callback's execution then
75- // this tock's after hook will be called, but not its destroy hook.
76- if ( destroyHooksExist ( ) )
77- emitDestroy ( asyncId ) ;
78-
79- const callback = tock . callback ;
80- if ( tock . args === undefined )
81- callback ( ) ;
82- else
83- Reflect . apply ( callback , undefined , tock . args ) ;
65+ const {
66+ [ async_id_symbol ] : asyncId ,
67+ [ trigger_async_id_symbol ] : triggerAsyncId ,
68+ callback,
69+ args
70+ } = tock ;
71+
72+ emitBefore ( asyncId , triggerAsyncId ) ;
73+
74+ try {
75+ if ( args === undefined )
76+ callback ( ) ;
77+ else
78+ callback ( ...args ) ;
79+ } finally {
80+ if ( destroyHooksExist ( ) )
81+ emitDestroy ( asyncId ) ;
82+ }
8483
8584 emitAfter ( asyncId ) ;
8685 }
@@ -91,23 +90,18 @@ function processTicksAndRejections() {
9190}
9291
9392class TickObject {
94- constructor ( callback , args , triggerAsyncId ) {
93+ constructor ( callback , args , asyncId , triggerAsyncId ) {
9594 // This must be set to null first to avoid function tracking
96- // on the hidden class, revisit in V8 versions after 6.2
95+ // on the hidden class, revisit in V8 versions after 7.4
9796 this . callback = null ;
9897 this . callback = callback ;
9998 this . args = args ;
10099
101- const asyncId = newAsyncId ( ) ;
102100 this [ async_id_symbol ] = asyncId ;
103101 this [ trigger_async_id_symbol ] = triggerAsyncId ;
104102
105- if ( initHooksExist ( ) ) {
106- emitInit ( asyncId ,
107- 'TickObject' ,
108- triggerAsyncId ,
109- this ) ;
110- }
103+ if ( initHooksExist ( ) )
104+ emitInit ( asyncId , 'TickObject' , triggerAsyncId , this ) ;
111105 }
112106}
113107
@@ -117,24 +111,25 @@ function nextTick(callback) {
117111 if ( typeof callback !== 'function' )
118112 throw new ERR_INVALID_CALLBACK ( callback ) ;
119113
120- if ( process . _exiting )
121- return ;
122-
123- var args ;
114+ let args ;
124115 switch ( arguments . length ) {
125116 case 1 : break ;
126117 case 2 : args = [ arguments [ 1 ] ] ; break ;
127118 case 3 : args = [ arguments [ 1 ] , arguments [ 2 ] ] ; break ;
128119 case 4 : args = [ arguments [ 1 ] , arguments [ 2 ] , arguments [ 3 ] ] ; break ;
129120 default :
130121 args = new Array ( arguments . length - 1 ) ;
131- for ( var i = 1 ; i < arguments . length ; i ++ )
122+ for ( let i = 1 ; i < arguments . length ; i ++ )
132123 args [ i - 1 ] = arguments [ i ] ;
133124 }
134125
135- if ( queue . isEmpty ( ) )
126+ if ( queue . isEmpty ( ) && ! process . _exiting )
136127 setHasTickScheduled ( true ) ;
137- queue . push ( new TickObject ( callback , args , getDefaultTriggerAsyncId ( ) ) ) ;
128+
129+ queue . push ( new TickObject ( callback ,
130+ args ,
131+ newAsyncId ( ) ,
132+ getDefaultTriggerAsyncId ( ) ) ) ;
138133}
139134
140135let AsyncResource ;
0 commit comments