The event loop finally clicked when I stopped calling it a loop
A practical mental model for tasks, microtasks, and why asynchronous JavaScript runs in the order it does.
The event loop is often explained as a small circle that continuously checks a queue. That picture is useful, but it hides the part that matters most: JavaScript runs jobs to completion, and the host decides when another job may begin.
Once I started thinking in terms of turns instead of a literal spinning loop, ordering became much easier to predict.
A turn, drawn plainly
A tiny experiment
console.log('first');queueMicrotask(() => console.log('microtask'));setTimeout(() => console.log('task'), 0);console.log('last');The current script finishes first. Microtasks drain next. Only then can the timer task start a new turn.
The rule I keep nearby
That gives us a compact rule worth remembering:
- Finish the current job.
- Drain the microtask queue.
- Let the host choose the next task.
The rule is smaller than most diagrams, but it explains more of the behavior I encounter in real code.