🔥 The Question That Confused Me
JavaScript is single-threaded…
So how does it handle things like:
- API calls
- Timers
- User interactions
…without blocking everything?
⚠️ The Problem
JavaScript can only execute one thing at a time on a single thread.
If a long-running task blocks the thread, the entire UI freezes.
👉 But real-world apps don’t work like that.
So something must be managing when async code runs.
⚙️ What is the Event Loop?
The Event Loop is a mechanism that coordinates execution between:
- The call stack (where code runs)
- The task queues (where async callbacks wait)
👉 It doesn’t execute code itself
👉 It decides when code should be executed
🧩 Core Pieces You Need to Know
1. Call Stack
- Where JavaScript executes code
- Follows LIFO (Last In, First Out)
- Runs synchronous code line by line
2. Web APIs
Things like:
setTimeoutfetch- DOM events
👉 These are handled by the browser, not JavaScript
Once completed, their callbacks are sent to queues.
3. Task Queue (Macrotask Queue)
Includes callbacks from:
setTimeoutsetInterval- DOM events
4. Microtask Queue
Higher priority queue that includes:
Promise.thenqueueMicrotask
⚡ Important Rule
👉 All microtasks are executed before macrotasks
How It All Works Together
- Synchronous code runs on the call stack
- Async operations go to Web APIs
- When done, callbacks move to queues
- The Event Loop checks:
- If the call stack is empty
- Then pushes tasks from queues to the stack
💥 Let’s Test This
let id="ex1"
console.log("Start");
setTimeout(() => {
console.log("Timeout");
}, 0);
Promise.resolve().then(() => {
console.log("Promise");
});
console.log("End");
👉 Pause and predict the output before reading further
✅ Output
Start
End
Promise
Timeout
Step-by-step Breakdown
-
Start→ goes to call stack → executed -
setTimeout→ goes to Web API → callback sent to task queue -
Promise.then→ goes to microtask queue -
End→ executed
Now stack is empty 👇
- Event Loop picks microtasks first →
Promise - Then picks macrotasks →
Timeout
💡 What Finally Clicked for Me
I used to think:
setTimeout(fn, 0)runs immediately
But actually:
- It always waits for the stack to be empty
- And it runs after microtasks
👉 This explains so many “weird” async bugs
🔚 Simple Summary
- JavaScript is single-threaded
- The Event Loop coordinates async execution
- Microtasks have higher priority than macrotasks
If you're learning JavaScript deeply, understanding this changes how you think about async code completely.
Top comments (0)