I had a weird timing bug in my app that came from switching from Bluebird to native promises. I fixed it, but am left with this oddity: Native promises seem to wiggle their way in between nextTick
and setImmediate
-- how? And is this supposed to happen? Where are promises supposed to go with regard to these?
~function(){
setTimeout (console.log.bind(console, 'timeout A'));
process.nextTick (console.log.bind(console, 'nextTick A'));
setImmediate (console.log.bind(console, 'setImmediate A'));
Promise.resolve().then(console.log.bind(console, 'promise'));
process.nextTick (console.log.bind(console, 'nextTick B'));
setImmediate (console.log.bind(console, 'setImmediate B'));
setTimeout (console.log.bind(console, 'timeout B'));
}();
Native yields:
nextTick A
nextTick B
promise undefined
setImmediate A
setImmediate B
timeout A
timeout B
Bluebird yields:
nextTick A
nextTick B
setImmediate A
promise undefined
setImmediate B
timeout A
timeout B
Native promises seem to wiggle their way in between nextTick and setImmediate -- how? And is this supposed to happen? Where are promises supposed to go with regard to these?
Yes, promises run after the microtask nextTick queue and before any tasks (like setImmediate) execute.
This is their intended behavior, and what we expect them to do in NodeJS. This was decided here and you can read about it here
Bluebird's different behavior
Bluebird's behavior predates native promises, bluebird 3.0 uses nextTick and microtask semantics for scheduling. Bluebird lets you manually override this behavior using Promise.setScheduler
with nextTick
as the scheduler (instead of setImmediate).
You can see the code here:
GlobalSetImmediate.call(global, fn)
NOTE THAT YOUR CODE SHOULD NOT RELY ON THESE BEHAVIORS ANYWAY.