Ever wondered how JavaScript knows when to run your .then()
block? Or why your console.log("done")
appears before a resolved promise result? Let’s break it down in this quick TidBit!
What is a Promise?
A Promise is JavaScript’s way of saying:
“I’ll give you a value… eventually!”
It’s a placeholder for a result that’s either:
- Fulfilled (Success)
- Rejected (Failure)
- Or still Pending
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Data loaded!");
}, 1000);
});
promise.then((data) => console.log(data));
When resolve("Data loaded!") is called, the .then()
block waits to execute — but where does it go meanwhile?
What is an Event Loop?
JavaScript is single-threaded. That means it can do one thing at a time. So how does it handle waiting, timers, and promises without freezing the app?
Enter the Event Loop.
It’s like a traffic controller — coordinating between:
- Call Stack (where code runs)
- Web APIs (like setTimeout, DOM)
- Callback Queue
- Microtask Queue (where .then() of Promises go)
How Event Loop Manages Promises?
Let’s see the order of execution:
console.log("Start");
Promise.resolve("Resolved").then((msg) => console.log(msg));
console.log("End");
Output:
Start
End
Resolved
But, Why?
Here’s how it plays out:
- console.log("Start") ➝ runs immediately (Call Stack)
- Promise.resolve(...).then(...) ➝ .then() is scheduled (Microtask Queue)
- console.log("End") ➝ also runs immediately
- After current stack is empty, Event Loop picks microtasks → .then() runs
This is why Resolved appears after End, even though the promise is already resolved!
Let’s spice it up with a setTimeout:
console.log("Start");
setTimeout(() => {
console.log("From setTimeout");
}, 0);
Promise.resolve().then(() => {
console.log("From Promise");
});
console.log("End");
Output:
Start
End
From Promise
From setTimeout
Here, Microtasks (Promises) are given priority over macrotasks (setTimeout, etc.).
Quick Recap
- Promises don’t run instantly — their .then() goes to the microtask queue.
- The Event Loop picks microtasks before other callbacks once the call stack is clear.
- Even a setTimeout(..., 0) will wait behind a resolved Promise!
So next time your Promise resolves “later,” remember — it’s not late. It’s just politely waiting its turn in the queue.
Want to learn further?
Learn about Event Loop along with JavaScript Promises, Call Stack, Task Queue Visually.
Day 27: How Your Async Code Works | JavaScript Event Loop Simplified! 🤩 - In this session, we’ll learn about how JavaScript executes code internally. This session uses visualizations to demonstrate the working of Call Stack, Event Loop, Promises, Web APIs, and more. Let's learn.
Top comments (1)
If only my own promises (like, “I’ll start my diet tomorrow”) waited so elegantly in a microtask queue instead of cutting straight to “macrotask: eat cookies immediately.” On a serious note, do you think the microtask/macrotask distinction is intuitive for most developers, or does it secretly delight in sowing chaos among unsuspecting souls with elusive race conditions?
Some comments may only be visible to logged-in visitors. Sign in to view all comments.