What the Heck Is the Event Loop Anyway?¶
Source: YouTube · JSConf EU 2014 · Philip Roberts
Overview¶
Philip Roberts delivers one of the most famous JavaScript talks ever, breaking down how JavaScript's event loop, call stack, and callback queue actually work. The talk is famous for its visual, intuitive explanations that finally make async JavaScript click.
Core Concepts¶
1. The Call Stack¶
JavaScript is single-threaded — it has one call stack and can do one thing at a time. The call stack is a data structure that records where in the program we are. When we step into a function, we push it onto the stack. When we return from a function, we pop it off.
2. Blocking¶
When things are slow on the stack (e.g., a synchronous network request that takes 30 seconds), the browser can't do anything else — it's "blocked." This is the root problem that the event loop solves.
3. The Event Loop & Callback Queue¶
- Callbacks (from
setTimeout, DOM events, AJAX requests) don't go directly onto the call stack. - They go into a callback queue (or task queue).
- The event loop constantly checks: "Is the call stack empty? If so, take the first callback from the queue and push it onto the stack."
4. The Browser's Role¶
The browser provides Web APIs (DOM, AJAX, setTimeout) that run in separate threads. When their work is done, they push the callback into the task queue. This is why JavaScript can do non-blocking I/O despite being single-threaded.
5. Microtasks vs Macrotasks¶
Modern JavaScript adds a refinement: microtasks (Promise callbacks, queueMicrotask) are processed before macrotasks (setTimeout, DOM events). This is why promises resolve before timers even when the timer fires first.
Key Takeaways¶
- JavaScript has one call stack — it can only do one thing at a time
- Slow synchronous operations block the stack (the "blocking" problem)
- The event loop continuously checks if the stack is empty and moves callbacks from the queue to the stack
- Browser Web APIs run in separate threads — they push callbacks to the queue when done
- Microtasks (Promises) are prioritized over macrotasks (setTimeout, DOM events)
- This architecture is why JavaScript can handle thousands of concurrent operations without multi-threading