Why JavaScript Promise Executes Before setTimeout (Event Loop Explained) ?

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.