DEV Community

Cover image for JavaScript's queueMicrotask(): Running Code ASAP (But Not Right Now)
Gajanan Patil
Gajanan Patil

Posted on

JavaScript's queueMicrotask(): Running Code ASAP (But Not Right Now)

Ever needed to run a piece of JavaScript code right after the current script finishes, but before the browser does anything else like rendering or handling timer callbacks? Meet queueMicrotask()!

It's a fundamental part of understanding JavaScript's concurrency model and the Event Loop.

What Does It Do?

In simple terms, queueMicrotask(callback) schedules a function (callback) to be executed in the microtask queue. Think of it as saying: "Run this function as soon as the current synchronous block of code is done executing, no matter what, and before handling less urgent things."

The Crucial Timing: Microtasks vs. Macrotasks

This is where queueMicrotask() shines and differs from something like setTimeout(callback, 0). Here's the general flow of the event loop:

  1. Execute the current synchronous script/task until the call stack is empty.
  2. Process the Microtask Queue: Execute all functions currently in the microtask queue, one by one, until the queue is empty. New microtasks added during this process are also executed before moving on.
  3. (Optional: Perform UI rendering updates, if needed and conditions allow).
  4. Process the Macrotask Queue: Take one task from the macrotask queue (like a setTimeout callback, setInterval, I/O operation, user interaction handler) and execute it. This execution might queue more microtasks.
  5. Repeat from step 2.

Key takeaway: Microtasks (queueMicrotask, Promise .then/.catch/.finally) have higher priority and run before the next macrotask (setTimeout, setInterval, rendering).

Why Use It?

  • Fine-grained Control: Perform cleanup or follow-up actions immediately after a block of code finishes, without yielding to the browser's rendering or other macrotasks.
  • Consistency with Promises: Promise callbacks are handled as microtasks. Using queueMicrotask allows you to schedule work with the same timing semantics.
  • Frameworks/Libraries: Useful internally in frameworks or libraries to schedule updates or reactions after state changes but before the browser might repaint.

Quick Example

console.log('Start');

// Macrotask - will run much later
setTimeout(() => {
  console.log('setTimeout (Macrotask)');
}, 0);

// Microtask - runs after 'End', before setTimeout
queueMicrotask(() => {
  console.log('queueMicrotask (Microtask)');
});

// Promise.then also queues a Microtask
Promise.resolve().then(() => {
  console.log('Promise.then (Microtask)');
});

console.log('End');

/*
Expected Output:
---------------
Start
End
queueMicrotask (Microtask)
Promise.then (Microtask)
setTimeout (Macrotask)
*/

🔴 Live TV: gajananpp/javascripts queuemicrotask running code asap but not right now cc - Pertandingan Hari Ini 🔴 Live TV: gajananpp/javascripts queuemicrotask running code asap but not right now cc - Pertandingan Hari Ini

Conclusion

queueMicrotask() gives you precise control to schedule code execution immediately after the current task, bypassing the queue for larger tasks like timers or rendering. It's a powerful tool when you need that "as soon as possible, but still async" behavior, especially when working alongside Promises.

It's been 3 (tough) years since I last wrote a post on dev.to and it felt nice writing post again. Will try to maintain streak going ahead.

Top comments (0)