JavaScript Event Loop Cheat Sheet
Covers the call stack, the task and microtask queues, and how the event loop orders callbacks from Promises, setTimeout, and other async APIs.
1 PageAdvancedMar 30, 2026
Call Stack & Synchronous Execution
JavaScript is single-threaded: one call stack.
javascript
function first() { second(); }function second() { third(); }function third() { console.log("deepest"); }first();// Stack grows: first -> second -> third// Each frame pops off as its function returns// JS is single-threaded: nothing else runs until the stack is empty
Execution Order: Sync, Microtask, Macrotask
Sync code always runs before any queued callback.
javascript
console.log("1: sync start");setTimeout(() => console.log("4: macrotask (setTimeout)"), 0);Promise.resolve().then(() => console.log("3: microtask (promise)"));console.log("2: sync end");// Output order: 1, 2, 3, 4// All sync code runs first, then ALL queued microtasks,// then one macrotask, then microtasks again, and so on.
Microtasks Drain Before the Next Macrotask
The microtask queue always empties completely first.
javascript
setTimeout(() => console.log("timeout"), 0);Promise.resolve() .then(() => console.log("promise 1")) .then(() => console.log("promise 2")); // Chained .then adds another microtaskqueueMicrotask(() => console.log("explicit microtask"));// Output: "promise 1", "explicit microtask", "promise 2", "timeout"// The ENTIRE microtask queue empties before the event loop// picks up the next macrotask (the setTimeout callback)
Blocking the Event Loop
Long synchronous work freezes everything else.
javascript
function blockFor(ms) { const end = Date.now() + ms; while (Date.now() < end) {} // Busy-wait -- freezes everything}console.log("start");setTimeout(() => console.log("this is delayed"), 0);blockFor(3000); // No callbacks, renders, or input can run for 3sconsole.log("end");// "this is delayed" only logs AFTER blockFor finishes,// even though the timer was 0ms
Key Concepts
Core vocabulary for the event loop.
- Call stack- LIFO structure tracking currently executing function frames, single-threaded
- Task queue (macrotasks)- Holds callbacks from setTimeout, setInterval, I/O, and UI events
- Microtask queue- Holds Promise .then/.catch/.finally callbacks and queueMicrotask(); higher priority than macrotasks
- Event loop- Continuously checks: if the stack is empty, run all microtasks, then one macrotask, repeat
- setTimeout(fn, 0)- Doesn't run immediately -- it queues fn as a macrotask after the current stack and all microtasks clear
- requestAnimationFrame- Schedules a callback before the next repaint, separate from both queues above
Pro Tip
A Promise chain can starve macrotasks (and even freeze the UI) if each .then() schedules another microtask indefinitely, since the loop won't move to setTimeout callbacks or rendering until the microtask queue is fully empty.
Was this cheat sheet helpful?
Explore Topics
#JavaScriptEventLoop#JavaScriptEventLoopCheatSheet#Programming#Advanced#Call#Stack#Synchronous#Execution#DataStructures#APIs#Concurrency#CheatSheet#SkillVeris
Advertisement
Sri Hayavadhana Info-Tech
Professional Web Designing Services
- Responsive Websites
- E-commerce Solutions
- SEO Friendly Design
- Fast & Secure
- Support & Maintenance