โ† Back to list

๐Ÿง  A Deep Inside Callback/Task Queue in JavaScript

Ever wondered what exactly happens behind the scenes when you write an async function, a setTimeout, or a Promise? What exactly is thisโ€ฆ

Sahil Rohera ยท 2025-04-24 03:45 ยท 7 claps ยท 1.4 min read
#javascript #event-loop-in-js #asynchronous-task-queue #callback-queue
Open on Medium โ†—
Wiki topics: ๐ŸŒ ยท Web Development

๐Ÿง  A Deep Inside Callback/Task Queue in JavaScript

Ever wondered what exactly happens behind the scenes when you write an async function, a setTimeout, or a Promise? What exactly is this callback queue, and how does the JavaScript engine decide what runs when?

Letโ€™s break it down.

So, What Is a Callback Queue?

The main purpose of the callback queue (also referred to as the task queue) is to hold callbacks that are tied to async operations. Once an async task completes, its associated callback is sent to this queue.

Now, here comes the role of the event loop. The event loop continuously checks whether the call stack is empty. If it is, it pulls the first callback from the queue and pushes it to the call stack, allowing it to be executed.

So far, so good.

But Hereโ€™s the Catchโ€ฆ

Letโ€™s say you have two async tasks:

setTimeout(() => console.log("Timeout"), 0);
Promise.resolve().then(() => console.log("Promise"));

According to what we just understood, it feels like setTimeout should get executed first, right? I mean, it appears first in the code.

But what actually happens is:

Promise
Timeout

Wait, what? Why is the Promise executing before the setTimeout, even though itโ€™s below it in the code?

The Real Deal โ€” Microtask vs Macrotask Queues

Hereโ€™s the missing piece: the callback queue isnโ€™t just one single queue. Itโ€™s actually a combination of two queues:

  • Microtask queue
  • Macrotask queue

And this matters. A lot.

Callbacks from Promises, async/await, and MutationObserver go into the microtask queue, which has higher priority.

Callbacks from setTimeout, setInterval, and some other events go into the macrotask queue.

So in our example:

  • The Promise's callback goes to the microtask queue.
  • The setTimeout's callback goes to the macrotask queue.

Now, when the call stack is empty, the event loop first checks the microtask queue and clears all microtasks before moving to any macrotasks.

Thatโ€™s why, even though setTimeout came first, its callback got executed later.

Diff between microtask and macrotask queue

Diff between microtask and macrotask queue


๋ฉ”ํƒ€๋ฐ์ดํ„ฐ
post_id
ff4f38cc800e
slug
a-deep-inside-callback-task-queue-in-javascript-ff4f38cc800e
url
https://medium.com/@sahilrohera10/a-deep-inside-callback-task-queue-in-javascript-ff4f38cc800e
canonical_url
https://medium.com/@sahilrohera10/a-deep-inside-callback-task-queue-in-javascript-ff4f38cc800e
author_url
https://medium.com/@sahilrohera10
status
ok
fetched_at
2026-08-06 08:14:01