First of all, the docs have clearly stated that in a I/O cycle, setImmediate() will always run before setTimeout(). What is bugging me is that they didn't explain why it functions like that, and looking for clues in the previous statements in their docs somehow pointed out to me the opposite (that setTimeout() should be called first). Here's why:
When the callback finishes, there are no more callbacks in the queue, so the event loop will see that the threshold of the soonest timer has been reached then wrap back to the timers phase to execute the timer's callback
and
Once the poll queue is empty the event loop will check for timers whose time thresholds have been reached. If one or more timers are ready, the event loop will wrap back to the timers phase to execute those timers' callbacks.
So it seems like the first thing the event loop prioritizes to do after exhaust the poll queue is to check the timers and wraps back there if they are timeouted. So in that regard it should be the setTimeout() be executed first.
I'm no advance programmer who can read source code in github to see how the libuv library works internally. Really appreciate some help from you guys.