以下是“practise01.js”文件中的代码,
function fn(name){
return f;
function f(){
var n = name;
console.log("Next TICK "+n+", ");
}
}
function myTimeout(time,msg){
setTimeout(function(){
console.log("TIMEOUT "+msg);
},time);
}
process.nextTick(fn("ONE"));
myTimeout(500,"AFTER-ONE");
process.nextTick(fn("TWO"));
myTimeout(500,"AFTER-TWO");
process.nextTick(fn("THREE"));
myTimeout(500,"AFTER-THREE");
process.nextTick(fn("FOUR"));
运行上面代码的输出是
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”。
那么它与我的第二种方法有何不同。
请解释我或给我一些指示
答案 0 :(得分:4)
节点文档实际上非常适合解释使用nextTick的时间和原因:
https://nodejs.org/api/process.html#process_process_nexttick_callback_args
它的作用:
这不是setTimeout(fn,0)的简单别名,它效率更高。它在事件循环的后续滴答中触发任何其他I / O事件(包括定时器)之前运行。
以及何时使用:
这在开发API时很重要,以便在构造对象之后但在任何I / O发生之前为用户提供分配事件处理程序的机会......
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()
答案 1 :(得分:1)
您在自己的帖子中得到了答案:
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仍然是相同的结果:
function fn(name){
return f;
function f(){
var n = name;
console.log("Next TICK "+n+", ");
}
}
function myTimeout(time,msg){
setTimeout(function(){
console.log("TIMEOUT "+msg);
},time);
}
process.nextTick(fn("ONE"));
myTimeout(0,"AFTER-ONE");// set timeout to execute in 0 seconds for all
process.nextTick(fn("TWO"));
myTimeout(0,"AFTER-TWO");
process.nextTick(fn("THREE"));
myTimeout(0,"AFTER-THREE");
process.nextTick(fn("FOUR"));
<强>结果
Next TICK ONE,
Next TICK TWO,
Next TICK THREE,
Next TICK FOUR,
TIMEOUT AFTER-ONE
TIMEOUT AFTER-TWO
TIMEOUT AFTER-THREE
当你使用process.nextTick
时,你基本上确保你作为参数传递的函数将在下一个tick中被立即调用,即。下一个事件循环的开始。这就是为什么你的下一个tick中的所有函数都在你的计时器之前执行,即。 setTimeout
下一个tick并不意味着下一秒它意味着nodejs eventloop的下一个循环。另外,下一个tick会确保您尝试调用的函数是异步执行的。并且下一个tick的优先级高于您的计时器,I / O操作等在事件循环中排队等待执行。如果要确保在下一个事件循环中而不是在指定时间之后执行代码,则应使用nextTick。 nextTick比定时器更有效,当你想确保你调用的函数是异步执行的。您可以在nodejs docs
答案 2 :(得分:0)
process.nextTick()的行为
Eventloop有多个阶段,每个阶段中都会执行不同类型的异步函数。
process.nextTick(callback[, ...args])
是nodeJS异步API的一部分。但这从技术上讲不是事件循环的一部分。
nextTickQueue
将在当前操作完成后处理,而不管事件循环的当前阶段如何。
每次在给定的事件循环阶段调用process.nextTick()
时,传递给process.nextTick()
的回调都会在事件循环继续之前得到解决。
为什么我们需要使用process.nextTick
对于API而言,100%同步或100%异步非常重要。考虑以下示例:
// WARNING! DO NOT USE! BAD UNSAFE HAZARD!
function maybeSync(arg, cb) {
if (arg) {
cb();
return;
}
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(callback)
而不是setTimeout(callback, 0)
有关更多信息,请参见here