Event Loop Visualizer
Step through the call stack, microtask queue and task queue to see exactly why asynchronous code runs in the order it does.
Intermediate~12 min
What you'll learn
- Trace how the call stack drains before any queued work runs
- Distinguish microtasks from macrotasks
- Predict the output order of mixed sync, promise and timer code
Interactive laboratory
Controls
Run, or step one tick at a time550 ms
console.log("A");
setTimeout(() => {
console.log("B");
}, 0);
Promise.resolve().then(() => {
console.log("C");
});
console.log("D");Call stack
top first- main()
Microtask queue
drained fullyempty
Task queue
one per turnempty
Output
consoleno output yet
- Phase
- Synchronous script
- Steps executed
- 0
- Microtasks run
- 0
- Tasks run
- 0
What happened?
Script loaded. main() is on the call stack.
Run or step the scenario to watch the stack drain, then the microtask queue, then one task per loop turn.
Why it happened
JavaScript executes on a single thread. The event loop coordinates which piece of work occupies that thread next.
Understanding the ordering rules removes most of the mystery from async bugs, race conditions and 'why did this log last?' surprises.
Key takeaways
- Microtasks run to exhaustion after every task, before rendering
- setTimeout(fn, 0) is a scheduling hint, not an immediate call
Tags
- event loop
- microtasks
- async
- runtime