Lessons · JavaScript · the event loop
What runs when
Code already running finishes first. Then queued promise callbacks run, then timers. setTimeout(fn, 0) means 'after the current work', not 'now'.
Hone is a place to practise programming. This is one of its lessons, written out in full and free to read without an account.
What it is for
Order bugs in the browser are event-loop bugs: a timer that fires after the data it needed, a promise callback that runs before the timer everyone expected first.
How to think about it
When output appears in a surprising order, classify each piece: synchronous, microtask (promise), or macrotask (timer, event). Sync first, then all microtasks, then one timer at a time.
Worked example
setTimeout(() => console.log("timeout"), 0);A timer, queued for after the current work.Promise.resolve().then(() => console.log("promise"));A microtask, queued for right after the current work.console.log("sync");Runs now.// prints: sync, promise, timeoutThe current code, then microtasks, then the timer.
Your turn
Run after the current work finishes.
setTimeout(fn, );
Solve one with the tests running
The trap
A long loop before setTimeout(fn, 0) delays fn by the whole loop. Nothing interrupts code that is already running.