Many JavaScript developers expect setTimeout(fn, 0) to run before everything else.
But when Promise and setTimeout are together, the output often surprises people.
Letβs understand this using a simple quiz example and a step-by-step explanation.
π The Code (Quiz Question)
console.log("Start");
setTimeout(() => {
console.log("Timeout");
}, 0);
Promise.resolve().then(() => {
console.log("Promise");
});
console.log("End");
β Question:
What will be the output?
A) Start End Timeout Promise
B) Start Promise End Timeout
C) Start End Promise Timeout
D) Start Timeout Promise End
β Correct Answer: C) Start End Promise Timeout
π§ Step-by-Step Execution (Very Important)
To understand this output, you need to know how JavaScript event loop works.
JavaScript uses:
- Call Stack
- Microtask Queue
- Task Queue
- Event Loop
Letβs go line by line.
πΉ Step 1: Synchronous Code Runs First
console.log("Start");
β‘οΈ Output:
Start
πΉ Step 2: setTimeout Goes to Task Queue
setTimeout(() => {
console.log("Timeout");
}, 0);
Even with 0ms, the callback:
- Does NOT execute immediately
- Goes to the Task Queue
πΉ Step 3: Promise Goes to Microtask Queue
Promise.resolve().then(() => {
console.log("Promise");
});
This callback goes into the Microtask Queue.
β οΈ Important:
Microtasks always have higher priority than tasks.
πΉ Step 4: Continue Synchronous Code
console.log("End");
β‘οΈ Output so far:
Start
End
πΉ Step 5: Event Loop Priority Rules
After synchronous code finishes:
1οΈβ£ Event loop executes all microtasks first
2οΈβ£ Then executes tasks (setTimeout)
So execution order:
- Promise callback
- setTimeout callback
π§Ύ Final Output
Start
End
Promise
Timeout
βοΈ Correct option: C
β‘ Key Rule to Remember (Interview Gold)
Microtasks (Promises) always run before Macrotasks (setTimeout).
π§ Simple Real-World Analogy
Imagine a company office π’
- Regular tasks β Emails (setTimeout)
- Urgent tasks β Phone calls (Promise)
Even if email is scheduled early, phone calls are answered first.
π Promise = urgent
π setTimeout = regular
β Common Misunderstanding
β setTimeout(fn, 0) runs immediately
β Promise waits for setTimeout
β Truth:
- Promise β Microtask queue
- setTimeout β Task queue
- Microtasks always win
π― Interview Tip
If asked:
βWhy does Promise execute before setTimeout?β
Answer:
Because Promise callbacks go into the microtask queue, and the event loop always processes microtasks before macrotasks.