The output is
timer1
timer2
timer1 nextTick
timer1 resolve
- All synchronous code is run (setting the timers).
- The event loop waits (poll) for the timers to fire, then their callbacks are all called.
- Then anything in the nextTick queue is run
- Then any resolved promises run their
then
handlers - If anything is in the nextTick or promises queue at this point (because other handlers added it) jump two steps up.
- The event loop waits (poll) for the timers to fire, then their callbacks are all called...
I don't remember this gist or its context but your output aligns with my understanding - microticks are always run between timers.
In general between every two macro-tasks that happen (like I/O or timers) microtasks (like process.nextTick or promise callbacks) need to run to completion - it's possible I created this gist in order to point out a bug in case this was not the case.