nl_tokens: Helper function for makeAwaitFunc () .
pl_tokens: function getExtraInfo ( traverse , topN ) { return function await ( ) { // Ensure this function is executing inside a fiber. if ( ! Fiber . current ) { throw new Error ( 'await functions, yield functions, and value-returning suspendable ' + 'functions may only be called from inside a suspendable function. ' ) ; } // Parse argument(s). If not a single argument, treat it like an array was passed in. if ( arguments . length === 1 ) { var expr = arguments [ 0 ] ; } else { expr = new Array ( arguments . length ) ; for ( var i = 0 ; i < arguments . length ; ++ i ) expr [ i ] = arguments [ i ] ; traverse = traverseInPlace ; } // Handle each supported 'awaitable' appropriately... var fiber = Fiber . current ; if ( expr && _ . isFunction ( expr . <mask> ) ) { // A promise: resume the coroutine with the resolved value, or throw the rejection value into it. // NB: ensure the handlers return null to avoid bluebird 3.x warning 'a promise was created in a //     handler but none were returned from it'. This occurs if the next resumption of the suspendable //     function (i.e. in the client's code) creates a bluebird 3.x promise and then awaits it. expr . then ( function ( val ) { return ( fiber . run ( val ) , fiber = null ) ; } , function ( err ) { return ( fiber . throwInto ( err ) , fiber = null ) ; } ) ; } else if ( _ . isFunction ( expr ) ) { // A thunk: resume the coroutine with the callback value, or throw the errback value into it. expr ( function ( err , val ) { if ( err ) fiber . throwInto ( err ) ; else fiber . run ( val ) ; fiber = null ; } ) ; } else if ( _ . isArray ( expr ) || _ . isPlainObject ( expr ) ) { // An array or plain object: resume the coroutine with a deep clone of the array/object, // where all contained promises and thunks have been replaced by their resolved values. // NB: ensure handlers return null (see similar comment above). var trackedPromises = [ ] ; expr = traverse ( expr , trackAndReplaceWithResolvedValue ( trackedPromises ) ) ; if ( ! topN ) { Promise . all ( trackedPromises ) . then ( function ( val ) { return ( fiber . run ( expr ) , fiber = null ) ; } , function ( err ) { return ( fiber . throwInto ( err ) , fiber = null ) ; } ) ; } else { Promise . some ( trackedPromises , topN ) . then ( function ( val ) { return ( fiber . run ( val ) , fiber = null ) ; } , function ( err ) { return ( fiber . throwInto ( err ) , fiber = null ) ; } ) ; } } else { // Anything else: resume the coroutine immediately with the value. setImmediate ( function ( ) { fiber . run ( expr ) ; fiber = null ; } ) ; } // Suspend the current fiber until the one of the above handlers resumes it again. return Fiber . yield ( ) ; } ; }