12.10
Compiler & Language Internals

JavaScript Event Loop

Visualize how the call stack, microtask queue, macrotask queue, and Web APIs interact to execute asynchronous JavaScript

Presets
1.0x
Call Stack
0
Microtasks
0
Macrotasks
0
Web APIs
0
Steps
0
Console Lines
0
Press Play or Step to begin execution
Source Code
1console.log("Start");
2setTimeout(() => {
3 console.log("Timeout 1");
4}, 0);
5setTimeout(() => {
6 console.log("Timeout 2");
7}, 0);
8console.log("End");
Console Output
No output yet...
Event Loop Cycle
Call Stack
Microtasks
Macrotasks
Web APIs
Call Stack
0 frames
Empty - waiting for work
Web APIs
0 active
No active Web APIs
Microtask Queue
0 pending
Empty
High priority: processed before macrotasks
Macrotask Queue
0 pending
Empty
Lower priority: one per loop iteration
How The Event Loop Works

JavaScript is single-threaded - it can only execute one thing at a time on the call stack. The event loop enables asynchronous behavior.

Execution Order:

  1. Run all synchronous code on the call stack
  2. When call stack empties, drain ALL microtasks (Promise .then, queueMicrotask)
  3. Process ONE macrotask (setTimeout, setInterval, I/O)
  4. Repeat from step 2
Microtasks
Promise.then, catch, finally, queueMicrotask, MutationObserver
Macrotasks
setTimeout, setInterval, setImmediate, I/O, UI rendering

Key insight: Microtasks can schedule more microtasks, and they ALL run before the next macrotask. This is why Promise callbacks always execute before setTimeout(fn, 0) callbacks.