How Does Event Loop Handle Promises? Ever Thought?
JavaScript
Async Programming
Frontend

How Does Event Loop Handle Promises? Ever Thought?

Learn how the promises are handled internally using event loop. This concept is essentials to debug and work with asyc programming.
3 min read

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
JS
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:

JS
console.log("Start");
Promise.resolve("Resolved").then((msg) => console.log(msg));
console.log("End");

Output:

BASH
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:

JS
console.log("Start");

setTimeout(() => {
    console.log("From setTimeout");
}, 0);

Promise.resolve().then(() => {
    console.log("From Promise");
});

console.log("End");

Output:

BASH
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.

Learn Full Stack

with tapaScript

By clicking Sign Up you re confirming that you agree with our Terms and Conditions.

newsletter

Don't forget to connect with us on