Skip to main content

Command Palette

Search for a command to run...

JavaScript queueMicrotask()

A method that can be found on the window interface helps queue a specified task to a safe time before control is returned to the browser's event loop.

Updated
4 min read
JavaScript queueMicrotask()
G

Hi Guys, my name is Gautam Jain and I have been fascinated by the wondrous aspects of technology ever since i was a kid, and after getting my personal computer after 12th standard my interest sky-rocketed.

I was so amazed by the cool operations one can perform using such small machine like a laptop and a phone. I begin to dive deep into the concepts of the computer science and to get more proficient in the field, enrolled for a Computer Science undergraduate degree.

I graduated with my bachelors degree from GNDEC, Ludhiana in august 2023. Throughout my course of 4 years, I invested in developing a good understanding core computer science concepts like discrete mathematics, Data Structures and Algorithms, Operating systems, Database management, CAM, Cyber Security, Compiler Design etc. Along with my academics, i also invested in developing my problem solving skills by actively indulging in competitive tournaments on platforms like GeeksforGeeks, Leetcode, Code studio, Hacker rank, Code chef and also made a routine of solving daily problem and challenges.

I worked together with my team (college friends and work colleagues) to create innovative, scalable and open-source projects and gained experience in software development by working as student SDE intern at E-Cell, TNP Cell and 11 mantras. I am currently working as a Programmer Analyst trainee in Cognizant Technology Solutions, brushing my skills in technologies' like Oracle Apps, Oracle SQL, Oracle PL/SQL, Java, JSP, JDBC, Spring etc.

I am always open to opportunities to further polish my skills and get a insight to how the daily world functions with the help of technology.

Actively Looking for open technology and project idea discussions.

A method that can be found on the window interface helps queue a specified task to a safe time before control is returned to the browser's event loop.

This function runs the specified tasks after the execution of other tasks has been done and control is about to go back to the browser's event loop. Basically, the tasks of queueMicrotask are executed just after the current call stack is empty before passing the execution to the event loop.

Syntax

Javascript

queueMicrotask(() => {
  // function
});

Parameters

function - A function to be executed when the browser engine determines it is safe to call your code.

Working

It's Similar to the working of setTimeout, but what's the difference between the two?

Basically, the queueMicrotask tasks are executed just after the call stack becomes empty and before returning control to the event loop while seTimeout tasks are executed from the event queue after the control has been returned to the event loop.

Still confused?

try running this piece of code in a browser console.

Javascript

setTimeout(() => {
    console.log('Executed asychronously by setTimeout()');
}, 0);

queueMicrotask(() => {
    console.log('Executed asychronously by queueMicrotask()');
});

Example

Consider a custom element firing a load event, that also maintains an internal cache of previously-loaded data.

A naive implementation might look like this:

Javascript

// target element -> myElement
MyElement.prototype.loadData = (url) => {
  if (this._cache[url]) {
    this._setData(this._cache[url]);
    this.dispatchEvent(new Event("load"));
  } else {
    fetch(url).then(res => res.arrayBuffer()).then(data => {
      this._cache[url] = data;
      this._setData(data);
      this.dispatchEvent(new Event("load"));
    });
  }
};

This naive implementation is problematic, however, in that it causes its users to experience inconsistent behaviour.

For example, code such as

Javascript

element.addEventListener("load", () => console.log("loaded"));
console.log("1");
element.loadData();
console.log("2");

will sometimes log "1, 2, loaded" (if the data needs to be fetched), and sometimes log "1, loaded, 2" (if the data is already cached). Similarly, after the call to loadData(), it will be inconsistent whether or not the data is set on the element.

To get a consistent ordering, queueMicrotask() can be used:

Javascript

MyElement.prototype.loadData = function (url) {
  if (this._cache[url]) {
    queueMicrotask(() => {
      this._setData(this._cache[url]);
      this.dispatchEvent(new Event("load"));
    });
  } else {
    fetch(url).then(res => res.arrayBuffer()).then(data => {
      this._cache[url] = data;
      this._setData(data);
      this.dispatchEvent(new Event("load"));
    });
  }
};

thus arranging the queued code to run after the JavaScript execution context stack empties, making the process consistent in ordering and updating elements.

NextTick vs MicroTasks

They are the same, in the way of both of them are to execute a task just after the execution of the current function or script.

They have different queues. The nextTick's queue is managed by node and the microtask one is managed by v8.

What does that mean?

The next tick queue is checked first after the current function/script execution, and then the microTask one.

There is no performance gain, the difference is that the nextTick queue will be checked first after the function/script execution and that must be taken into account. If you never use nextTick and only use queueMicrotask you will have the same behaviour of just using nextTick (taking into account that your tasks will be placed in a queue with other microtasks).

The use case could be to execute tasks before any microtask, for example, before a promise's then and/or catch. It is worth noting that promises use microtask so, any callback added to then/catch will be added to the microtask queue and its execution will be performed when the nextTick queue is empty.

Imagine this code

Javascript

let i = 1;

queueMicrotask(() => console.log(i));
process.nextTick(() => i++);

Output

2

the output will be 2, due to nextTick getting executed first.

but for this Code

Javascript

let i = 1;

queueMicrotask(() => console.log(i));
process.nextTick(() => queueMicrotask(() =>i++));

Output

1

you get output 1

Note

This needs to understand that scheduling a lot of microtasks has the same performance downsides as running a lot of synchronous code. Both will prevent the browser from doing its work, such as rendering.

References

https://html.spec.whatwg.org/

https://stackoverflow.com/questions/55467033/difference-between-process-nexttick-and-queuemicrotask

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

108 views