Javascript 为什么以及何时使用process.nextTick?

Javascript 为什么以及何时使用process.nextTick?,javascript,node.js,Javascript,Node.js,下面是“practise01.js”文件中的代码 运行上述代码的输出是 rahul@rahul:~/myPractise/PlainNodeJSPractise01/Process$ node practise01.js Next TICK ONE, Next TICK TWO, Next TICK THREE, Next TICK FOUR, TIMEOUT AFTER-ONE TIMEOUT AFTER-TWO TIMEOUT AFTER-THR

下面是“practise01.js”文件中的代码

运行上述代码的输出是

rahul@rahul:~/myPractise/PlainNodeJSPractise01/Process$ node practise01.js                  

Next TICK ONE, 
Next TICK TWO, 
Next TICK THREE, 
Next TICK FOUR, 
TIMEOUT AFTER-ONE
TIMEOUT AFTER-TWO
TIMEOUT AFTER-THREE
现在我在“practise02.js”中编写了代码,没有使用process.nextTick,如下所示

function myTimeout(time,msg){
  setTimeout(function(){
        console.log("TIMEOUT "+msg);
  },time);  
}

function fn(name){
  return f;

  function f(){
    var n = name;
    console.log("Next TICK "+n+", ");       
  }
}

fn("ONE")();
myTimeout(500,"AFTER-ONE");
fn("TWO")();
myTimeout(500,"AFTER-TWO");
fn("THREE")();
myTimeout(500,"AFTER-THREE");
fn("FOUR")();
运行上述代码后,输出为

rahul@rahul:~/myPractise/PlainNodeJSPractise01/Process$ node practise02.js 
Next TICK ONE, 
Next TICK TWO, 
Next TICK THREE, 
Next TICK FOUR, 
TIMEOUT AFTER-ONE
TIMEOUT AFTER-TWO
TIMEOUT AFTER-THREE
如果您看到两个输出是相同的

那么在这种情况下,我需要使用process.nextTick

当我尝试阅读更多内容时,我了解到,如果eventloop为空,我是否需要立即执行某些函数,而不是执行“process.nextTick”

那么它与我的第二种方法有什么不同呢


请给我解释一下或给我一些建议

你在你的帖子中有你的答案,你可以在下面与我们分享你的成果:

rahul@rahul:~/myPractise/PlainNodeJSPractise01/Process$ node practise02.js 
Next TICK ONE, 
Next TICK TWO, 
Next TICK THREE, 
Next TICK FOUR, 
TIMEOUT AFTER-ONE
TIMEOUT AFTER-TWO
TIMEOUT AFTER-THRE
如果我们将超时时间间隔从500更改为0,结果仍然相同:
函数fn(名称){
返回f;
函数f(){
var n=名称;
console.log(“下一个勾号“+n+”,”);
}
}
函数myTimeout(时间,msg){
setTimeout(函数(){
console.log(“超时”+msg);
},时间);
}
进程。下一个进程(fn(“一”);
myTimeout(0,“一次之后”);//将超时设置为在0秒内执行所有
进程。下一个进程(fn(“两个”);
myTimeout(0,“两次之后”);
进程。下一个进程(fn(“三”);
myTimeout(0,“三次之后”);

进程。下一个进程(fn(“四”)节点文档实际上很好地解释了使用nextTick的时间和原因:

它的作用是:

这不是setTimeout(fn,0)的简单别名,它更有效。它在事件循环的后续计时触发任何附加I/O事件(包括计时器)之前运行

以及何时使用:

在开发API时,这一点很重要,以便用户有机会在构建对象之后但在发生任何I/O之前分配事件处理程序


首先让我们了解process.nextTick()的行为。

Eventloop有几个阶段,每个阶段执行不同类型的异步函数

process.nextTick(回调[,…args])
是nodeJS异步API的一部分。但从技术上讲,它不是事件循环的一部分

nextTickQueue
将在当前操作完成后处理,无论事件循环的当前阶段如何

在eventloop的给定阶段,每当调用
process.nextTick()
时,传递给
process.nextTick()
的回调将在事件循环继续之前解析

为什么我们需要使用
process.nextTick

对于API来说,100%同步或100%异步是非常重要的。考虑这个例子:

//警告!不要使用!严重的不安全危险!
函数可能同步(arg,cb){
如果(arg){
cb();
返回;
}
fs.stat('file',cb);
}
const maybeTrue=Math.random()>0.5;
maybeSync(maybeTrue,()=>{
foo();
});
bar();
不清楚是先调用
foo()
还是
bar()
。 以下方法更好:

function definitelyAsync(arg, cb) {
  if (arg) {
    process.nextTick(cb);
    return;
  }

  fs.stat('file', cb);
}
@Johannes Merz已经在他的回答中提到了为什么使用
process.nextTick(回调)
而不是
setTimeout(回调,0)


有关更多信息,请参阅

您没有看到差异,因为您只使用了
console.log
process.nextTick
。做控制台日志,下一个勾选,console.log,你就会看到区别了。我不明白。这是我试图了解下一个滴答声的第五篇文章,它说下一个滴答声将立即调用
,即下一个事件循环的开始。但我在哪里都没看到一个环。您能指定所谓的“事件循环”在哪里吗?我认为“[…]将在下一个勾选中立即调用,即下一个事件循环的开始[…](和其他)有点误导。事件循环由几个阶段组成,process.nextTick不会在下一个循环开始时启动,而是在当前操作process之后立即启动。nextTick()会在同一阶段立即启动。不适用于下一个事件循环@晕船就在这里提到。在给定的阶段中,每当调用process.nextTick()时,传递给process.nextTick()的所有回调都将在事件循环继续之前得到解决。@晕船感谢您指出它,删除了误导性引用,如果您觉得有任何其他不一致,请更新答案
function definitelyAsync(arg, cb) {
  if (arg) {
    process.nextTick(cb);
    return;
  }

  fs.stat('file', cb);
}
definitelyAsync(true, () => {
  foo();
});
bar(); // will now allways be called before foo()
function definitelyAsync(arg, cb) {
  if (arg) {
    process.nextTick(cb);
    return;
  }

  fs.stat('file', cb);
}