Search code examples
javascriptv8event-loop

JS event Loop confuse


I am pretty new to JS event loop, I wonder if anyone could give me a brief walk thru about how js engine run this:

function start(){
  setTimeout(function(){
    console.log("Timeout")
  }, 0)
  setImmediate(function(){
    console.log("Immediate")
  })
  process.nextTick(function(){
    console.log("next tick")
  })
}

The result is :

next tick
Timeout
Immediate

I thought when JS engine runs this,

  1. it parses the script, set Timer, set Immediate, set nextTick queue, then goes into POLL stage, checks if anything queued there(nothing in this case)
  2. Before moving to CHECK stage, it runs nextTick queue, print "next tick".
  3. Moves to CHECK stage, run immediate queue, print "Immediate"
  4. Loops back to TIMER stage, print "Timeout"

My confuse is why setTimeout print out before Immediate?

PS,

After I set Timeout delay from 0 to 3 or more, then the order is:

next tick
Immediate
Timeout

But this still does not explain why previous order JS event loop runs.

I wonder is there anything I missed?


Solution

  • setImmediate queues the function behind whatever I/O, event, callbacks that are already in the event queue. So, in this case setTimeout is already in queue.

    I think you should read https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/ again. It has answer to all your questions. I am quoting following lines from above mentioned document

    setImmediate() vs setTimeout()

    setImmediate and setTimeout() are similar, but behave in different ways depending on when they are called.

    setImmediate() is designed to execute a script once the current poll phase completes. setTimeout() schedules a script to be run after a minimum threshold in ms has elapsed.

    The order in which the timers are executed will vary depending on the context in which they are called.

    Understanding process.nextTick()

    process.nextTick() is not technically part of the event loop. Instead, the nextTickQueue will be processed after the current operation completes, regardless of the current phase of the event loop.

    Looking back at our diagram, any time you call process.nextTick() in a given phase, all callbacks passed to process.nextTick() will be resolved before the event loop continues. This can create some bad situations because it allows you to "starve" your I/O by making recursive process.nextTick() calls, which prevents the event loop from reaching the poll phase.