5448

Difference between process.nextTick and queueMicrotask

<h3>Question</h3>

Node 11.0.0 adds queueMicrotasks as experimental. The doc says it is similar to process.nextTick but the queue is managed by V8 instead of Node.js. What would be the use case to use queueMicrotasks instead of process.nextTick? Will there be any performance gain using one over another?


<h3>Answer1:</h3>
Queues

We can find different queues (show in check priority order after finish a function/script execution):

<ul><li>nextTick </li> <li>microTasks</li> <li>timers (expired)</li> <li>immediate</li> </ul>

How the queues are checked?

First, nextTick queue is checked to get tasks for its execution, once it is exhausted, the microTasks queue is checked. After finishing the tasks in the microtask queue the process of checking nextTick and microTasks queues are repeated until the queues have been emptied.

The next queue to check is the timers one and in the end the immediate queue.

Differences

It is 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 is it means?

The nextTick queue is checked in first place 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 behavior of just using nextTick (taking into account that your tasks will be placed in a queue with another microtasks)

The use case could be to execute tasks before any microtask, for example, before a promise then and/or catch. It 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 nextTick queue is empty.

Example

After the execution of this code:

function task1() { console.log('promise1 resolved'); } function task2() { console.log('promise2 resolved'); process.nextTick(task10); } function task3() { console.log('promise3 resolved'); } function task4() { console.log('immediate 1'); } function task5() { console.log('tick 1'); } function task6() { console.log('tick 2'); } function task7() { console.log('microtask 1'); } function task8() { console.log('timeout'); } function task9() { console.log('immediate 2'); } function task10() { console.log('tick3'); queueMicrotask(task11); } function task11() { console.log('microtask 2'); } Promise.resolve().then(task1); Promise.resolve().then(task2); Promise.resolve().then(task3); setImmediate(task4); process.nextTick(task5); process.nextTick(task6); queueMicrotask(task7); setTimeout(task8, 0); setImmediate(task9);

Execution

<ul><li>nextTick: task5 | task6</li> <li>microTasks: task1 | task2 | task3 | task7</li> <li>timers: task8</li> <li>immediate: task4 | task9</li> </ul>

Step 1: execute all tasks in nextTick queue

<ul><li>nextTick: EMPTY</li> <li>microTasks: task1 | task2 | task3 | task7</li> <li>timers: task8</li> <li>immediate: task4 | task9</li> </ul>

output:

<ul><li>tick 1</li> <li>tick 2</li> </ul>

Step 2: execute all tasks in microTasks queue

<ul><li>nextTick: task10</li> <li>microTasks: EMPTY</li> <li>timers: task8</li> <li>immediate: task4 | task9</li> </ul>

output:

<ul><li>tick 1</li> <li>tick 2</li> <li>promise 1 resolved</li> <li>promise 2 resolved</li> <li>promise 3 resolved</li> <li>microtask 1</li> </ul>

Step 3: execute all tasks in nextTick queue (there is a new task added by the execution of microtask (task2))

<ul><li>nextTick: EMPTY</li> <li>microTasks: task11</li> <li>timers: task8</li> <li>immediate: task4 | task9</li> </ul>

output:

<ul><li>tick 1</li> <li>tick 2</li> <li>promise 1 resolved</li> <li>promise 2 resolved</li> <li>promise 3 resolved</li> <li>microtask 1</li> <li>tick 3</li> </ul>

Step 4: execute all tasks in microTasks queue (there is a new task added by the execution of task10)

<ul><li>nextTick: EMPTY</li> <li>microTasks: EMPTY</li> <li>timers: task8</li> <li>immediate: task4 | task9</li> </ul>

output:

<ul><li>tick 1</li> <li>tick 2</li> <li>promise 1 resolved</li> <li>promise 2 resolved</li> <li>promise 3 resolved</li> <li>microtask 1</li> <li>tick 3</li> <li>microtask 2</li> </ul>

Step 5: No more tasks in nextTick and microTasks queues, next execute timers queue.

<ul><li>nextTick: EMPTY</li> <li>microTasks: EMPTY</li> <li>timers: EMPTY</li> <li>immediate: task4 | task9</li> </ul>

output:

<ul><li>tick 1</li> <li>tick 2</li> <li>promise 1 resolved</li> <li>promise 2 resolved</li> <li>promise 3 resolved</li> <li>microtask 1</li> <li>tick 3</li> <li>microtask 2</li> <li>timeout</li> </ul>

Step 6: No more tasks in (expired) timers queue, execute tasks in immediate queue

<ul><li>nextTick: EMPTY</li> <li>microTasks: EMPTY</li> <li>timers: EMPTY</li> <li>immediate: EMPTY</li> </ul>

output:

<ul><li>tick 1</li> <li>tick 2</li> <li>promise 1 resolved</li> <li>promise 2 resolved</li> <li>promise 3 resolved</li> <li>microtask 1</li> <li>tick 3</li> <li>microtask 2</li> <li>timeout</li> <li>immediate 1</li> <li>immediate 2</li> </ul>

As we can see there is no performance reason to choose one or another, the chosen decision depends on our needs and what needs to be done and when.

Imagine this code:

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

The output will be 2 due to nextTick queue is first checked first.

but if you do

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

You will get 1.

With examples, I want to make you see that the uses cases come from your needs of what and when you need to perform a task. And the important thing is taking into account that then/catch callbacks in a promise are microtasks and will be executed after nextTick tasks, take into account this is important to avoid errors (as stated in the behind example).

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

Recommend

  • Why do we have to put an asterisk on method parameter types in Objective-C?
  • Laravel Blade - custom method for html block?
  • macOS Swift Safari-like tabs
  • How to define redirect page for protected pages
  • dropdown value null when using, viewmodel & modelbinder in asp.net mvc
  • Firebase reverse dns lookup ENOTFOUND error node.js dns
  • ob_start() failed to create buffer in laravel three
  • Use a Batch File to list files and allow the user to select which file to copy into a new destinatio
  • Eclipse (ctrl+space) content assist hook
  • Is there way to structure a QueryExpression so that you could dynamically handle a unknown number of
  • NextJS auth with an external server
  • Multiple custom authentication with spring security
  • typescript multidimensional array with different types
  • how to reload page after uploading images
  • how can i close the resultSet, prepareStatement, conn in several methods below to avoid rs close and
  • device tree overlay phandle
  • Pyinstaller GLIBC_2.15 not found
  • Create One-To-One relationship between table and view in EF4?
  • Parallelization via JDBC - Pyspark - How does parallelization work using JDBC?
  • Hibernate Idempotent Update
  • Background beacon detection and Notification (Both iOS and Android) for Eddystone beacon?
  • Move elements from a listbox to another
  • jqGrid Filter Toolbar and Date and Select filters
  • Azure NodeJS Error: ENOENT, open 'D:\\home\\site\\wwwroot\\bin\\views\\'
  • VB.NET and LINQ - Group by in a DataTable
  • Get name of days between two date in ios?
  • playing mp3 from nsbundle
  • Set SelectedIndex of ListView in FlipView_SelectionChanged event
  • Wireshark Display Filter for Unique Source/Destination IP and Protocol
  • Thumbnails for mxml components in Flex
  • How to check if a database and tables exist in sql server in a vb .net project?
  • How to make 100% div height between header and footer?
  • Terminal run dalvikvm with am.jar
  • VSTS work items list through REST API
  • What is the best way to cache and reuse immutable singleton objects in Java?
  • Bad automatic Triangulation with Mayavi for coloring a surface known only by its corner
  • Android Library Projects on Windows and Mac
  • Angular FormGroup won't update it's value immediately after patchValue or setValue
  • Write to .csv file with PHP (Commas in Data Error)
  • ARKit code issue {unknown error -1=ffffffffffffffff error: Task failed with exit 1}