Course contentsShow
← Node.js
Lesson 176 of 1,9803. Asynchronous Patterns and Flow ControlFree lesson

Understanding the Microtask Queue

You will distinguish between macro and microtasks to predict the execution order of promises within the event loop.

In this lesson, you will learn how to predict the exact order of code execution by distinguishing between the "Macro" and "Micro" task queues in Node.js.

The Two Queues

To manage asynchronous code, Node.js uses an event loop that sorts tasks into different "waiting areas." Think of the Macrotask Queue as the main waiting room for heavy-lifting operations like setTimeout, setInterval, or file I/O operations.

The Microtask Queue, however, is a high-priority VIP line. This queue is primarily populated by Promises (.then, .catch, .finally).

The golden rule of the event loop is this: The engine will always empty the entire Microtask Queue before moving on to the next Macrotask.

Seeing it in Action

Look at this code snippet. Can you guess which one prints first?

console.log('Start');

setTimeout(() => {
  console.log('Macrotask (setTimeout)');
}, 0);

Promise.resolve().then(() => {
  console.log('Microtask (Promise)');
});

console.log('End');

The execution order will be:

  1. Start (Synchronous code runs first)
  2. End (Synchronous code runs next)
  3. Microtask (Promise) (The event loop checks the Microtask queue before looking at the Macrotasks)
  4. Macrotask (setTimeout) (Finally, the event loop handles the Macrotask)

Even though the setTimeout has a delay of 0 milliseconds, it is still a Macrotask. Because the Promise is a Microtask, it jumps to the front of the line. If you had ten Promises queued up, Node.js would finish every single one of them before it allowed the setTimeout callback to execute.

Why does this matter?

Understanding this distinction prevents "race conditions" where your code behaves unexpectedly. If you rely on setTimeout to handle data that a Promise is supposed to provide, you might find your logic failing because the Promise microtask hasn't resolved yet when your timeout fires. By grasping the priority of the Microtask queue, you gain full control over the flow of your asynchronous operations.

Key Takeaway: The event loop processes all pending Microtasks immediately after the current script finishes, prioritizing them over any waiting Macrotasks.