节点11.0.0将queueMicrotasks
添加为实验性。 doc说它与process.nextTick
类似,但是队列由V8而不是Node.js管理。用queueMicrotasks
代替process.nextTick
的用例是什么?互相使用会提高性能吗?
答案 0 :(得分:4)
我们可以找到不同的队列(在完成功能/脚本执行后按检查优先级顺序显示):
如何检查队列?
首先,检查nextTick队列以获取执行任务,一旦耗尽,就检查microTasks队列。完成微任务队列中的任务后,检查过程 重复执行nextTick和microTasks队列,直到清空队列为止。
要检查的下一个队列是计时器,最后是立即队列。
这是相同的,两者都是在执行当前函数或脚本之后立即执行任务。
他们有不同的队列。 nextTick的队列由节点管理,微任务一个由v8管理。
这是什么意思?
在当前函数/脚本执行之后,首先检查nextTick队列,然后再检查microTask。
没有性能提升,区别在于在执行函数/脚本之后将首先检查nextTick队列,并且必须将其考虑在内。 如果您从不使用nextTick,而仅使用queueMicrotask,则您将具有仅使用nextTick的相同行为(考虑到您的任务将与另一个微任务一起放入队列中)
用例可以是在执行任何微任务之前执行任务,例如在promise then和/或catch之前执行任务。值得注意的是,promise使用微任务,因此,添加到then / catch的任何回调都将添加到微任务队列中,并且当nextTick队列为空时将执行它。
执行此代码后:
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);
步骤1:执行nextTick队列中的所有任务
输出:
步骤2:执行microTasks队列中的所有任务
输出:
步骤3:执行nextTick队列中的所有任务(通过执行微任务(任务2)添加了新任务)
输出:
步骤4:执行microTasks队列中的所有任务(执行task10会添加一个新任务)
输出:
步骤5:nextTick和microTasks队列中没有更多任务,next execute timers队列中。
输出:
步骤6 :(过期的)计时器队列中没有更多任务,立即队列中执行了任务
输出:
我们看到没有选择一个或另一个性能的理由,选择的决定取决于我们的需求以及需要做什么以及何时完成。
想象一下这段代码:
let i = 1;
queueMicrotask(() => console.log(i));
process.nextTick(() => i++);
由于首先检查nextTick队列,输出将为2。
但如果您这样做
let i = 1;
queueMicrotask(() => console.log(i));
process.nextTick(() => queueMicrotask(() =>i++));
您将得到1。
通过示例,我想使您看到用例来自于您对执行任务的内容和时间的需求。而且重要的是要考虑到promise中的then / catch回调是微任务,将在nextTick任务之后执行,要考虑到这一点对于避免错误很重要(如后面的示例所述)。