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));
Enter fullscreen mode Exit fullscreen mode

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");
Enter fullscreen mode Exit fullscreen mode

Output:

Start
End
Resolved
Enter fullscreen mode Exit fullscreen mode

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");
Enter fullscreen mode Exit fullscreen mode

Output:

Start
End
From Promise
From setTimeout
Enter fullscreen mode Exit fullscreen mode

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.