6.2 — The event loop
Last lesson ended on a cliffhanger: the timer rings off the thread — so how does its callback get back onto the one and only stack without crashing into whatever's running? The answer is the most famous diagram in JavaScript: the event loop.
Four parts, one rule. The call stack you know. The Web APIs — the environment's waiting room where timers tick and network replies land.
The callback queue — a first-in-first-out line of callbacks ready to run. And the event loop itself, a tireless arm with a single rule: is the stack empty? Then move exactly one callback from the queue onto it.
Learn this machine and setTimeout(fn, 0) stops being a riddle forever.
console.log("1");
setTimeout(() => {
console.log("3");
}, 0);
console.log("2");Meet the machine, four parts. The call stack — the ONLY place JavaScript executes. The Web APIs — the environment’s own machinery, running on separate threads. The callback queue — a first-in-first-out waiting line. And the event loop — an arm that checks one thing, forever. Nothing is moving yet.
The deeper story, with the real names for things — this part is what turns “I saw it” into “I can explain it.”
Where do clicks fit? Same machine, no special case: the browser watches the mouse (Web-API side), and a click puts your handler in the queue. That's why 6.1's blocked page had dead buttons — the handlers were queued behind a stack that never emptied. Every "later" in the browser — timers, clicks, network replies, even Playwright's simulated events — is a callback taking its turn through this one queue.
💼 On the job — the event loop is not part of the JavaScript engine. V8 has the stack and heap; the loop, timers and queue live in the environment — the browser here; Node's version arrives in 9.6.
Also the queue is honest FIFO: two timers with equal delay run in scheduling order — your exercise proves it.
One seat is still empty in this diagram: promises (lesson 6.4) don't use this queue — they get a faster one. That's lesson 6.5, and it's the last piece of the machine.
⌨️ the ticket counter
Choreograph four prints so the output proves you can predict the machine: two scheduled callbacks must both wait for ALL the sync code — and keep their queue order.
requirements:
- Print
"opens". - Schedule (0ms) a print of
"ticket 1 served", then schedule (0ms) a print of"ticket 2 served". - Print
"queue forms". Required output order: opens, queue forms, ticket 1 served, ticket 2 served — sync first, then the queue in first-in-first-out order.
when you press RUN, the console must show exactly:
✏️ Quick check 1
Type the FULL output order, separated by spaces:
console.log("a");
setTimeout(() => console.log("b"), 0);
console.log("c");✏️ Quick check 2
The event loop moves a callback onto the stack only when the stack is ___. Type the word.
✏️ Quick check 3
A click happens while your code runs a long sync loop. Where does the click’s handler wait — the stack, or the queue? Type it.
🗣️ Now teach it back
The interview favorite: “Explain the event loop.” Name the four parts, the one rule, and use setTimeout(fn, 0) as your worked example — including why its callback can never run before the sync code finishes.
Write it as if your friend is sitting next to you. Saved to your journal — future-you will use these notes to teach others.