Blog
queueMicroTask in JavaScript

queueMicroTask in JavaScript

In this article, we analyze queueMicroTask function in React source code
React uses queueMicroTask in a file named ReactAct.js. This is a public API, act.

act is a test helper to apply pending React updates before making assertions.

await act(async actFn)

ReactAct.js has a lot of code, let’s narrow down our focus on to queueMicroTask.

Where is queueMicroTask called in ReactAct.js?

queueSeveralMicrotasks is found at the end of this ReactAct.js file and calls queueMicroTask with a callback and has detailed comment explaining its purpose.

queueSeveralMicrotasks is found to be called in two places:

// Warn if the an `act` call with an async scope is not awaited. In a
 // future release, consider making this an error.
 queueSeveralMicrotasks(() => {
   if (!didAwaitActCall && !didWarnNoAwaitAct) {
     didWarnNoAwaitAct = true;
     console.error(
       'You called act(async () => …) without await. ' +
       'This could lead to unexpected testing behaviour, ' +
       'interleaving multiple act calls and mixing their ' +
       'scopes. ' +
       'You should - await act(async () => …);',
     );
   }
 });
// Warn if something suspends but the `act` call is not awaited.
// In a future release, consider making this an error.
if (queue.length !== 0) {
 queueSeveralMicrotasks(() => {
 if (!didAwaitActCall && !didWarnNoAwaitAct) {
   didWarnNoAwaitAct = true;
   console.error(
     'A component suspended inside an `act` scope, but the ' +
     '`act` call was not awaited. When testing React ' +
     'components that depend on asynchronous data, you must ' +
     'await the result:\n\n' +
     'await act(() => …)',
   );
   }
 });
}

Now that we saw how queueMicroTask is used, let’s now understand the definition of queueMicroTask.

queueMicroTask

The queueMicrotask() method of the Window interface queues a microtask to be executed at a safe time prior to control returning to the browser’s event loop.

The microtask is a short function which will run after the current task has completed its work and when there is no other code waiting to be run before control of the execution context is returned to the browser’s event loop.

This lets your code run without interfering with any other, potentially higher priority, code that is pending, but before the browser regains control over the execution context, potentially depending on work you need to complete.

Read more about queueMicroTask at MDN Docs.

Example:

Here’s an example of how microtasks and macrotasks interact with the browser’s execution:

console.log('Synchronous 1'); // 1
Promise.resolve().then(() => {
 console.log('Microtask 1'); // 3
});
console.log('Synchronous 2'); // 2
setTimeout(() => {
 console.log('Macrotask 1'); // 5
}, 0);
console.log('Synchronous 3'); // 4

Breakdown:

The synchronous code runs first, outputting:
‘Synchronous 1’
‘Synchronous 2’
‘Synchronous 3’

Before the browser gets a chance to handle any pending rendering or macrotasks, the microtask queue is processed:

The Promise.resolve().then(…) callback is added to the microtask queue and is executed right after the synchronous code block is finished, logging:
‘Microtask 1’

After the microtask queue is emptied, the browser regains control and can:

Run macrotasks, like the setTimeout callback, which logs:

‘Macrotask 1’

Final output

Synchronous 1
Synchronous 2
Synchronous 3
Microtask 1
Macrotask 1

About me:

Hey, my name is Ramu Narasinga. I study large open-source projects and create content about their codebase architecture and best practices, sharing it through articles, videos.

I am open to work on interesting projects. Send me an email at ramu.narasinga@gmail.com

My Github — https://github.com/ramu-narasinga

My website — https://ramunarasinga.com

My Youtube channel — https://www.youtube.com/@thinkthroo

Learning platform — https://thinkthroo.com

Codebase Architecture — https://app.thinkthroo.com/architecture

Best practices — https://app.thinkthroo.com/best-practices

Production-grade projects — https://app.thinkthroo.com/production-grade-projects

References:

  1. https://developer.mozilla.org/en-US/docs/Web/API/Window/queueMicrotask

  2. https://github.com/facebook/react/blob/5d19e1c8d1a6c0b5cd7532d43b707191eaf105b7/packages/react/src/ReactAct.js#L361

  3. https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide

  4. https://react.dev/reference/react/act

  5. https://javascript.info/event-loop