据我了解,process.nextTick()
和setImmediate()
之间存在以下差异:
process.nextTick()
安排的回调将在进入下一个事件循环之前执行,而由setImmediate()
安排的回调将仅在每个事件循环中执行一次。process.nextTick()
的递归调用会导致程序挂起,而setImmediate()
的递归调用则不会。 然后我写了一些测试代码来验证上面的陈述,这是我的代码:
process.nextTick(function() {
console.log('nextTick1');
});
process.nextTick(function() {
console.log('nextTick2');
});
setImmediate(function() {
console.log('setImmediate1');
process.nextTick(function() {
console.log('nextTick3');
});
});
setImmediate(function() {
console.log('setImmediate2');
});
我的预期结果应为
nextTick1,nextTick2,setImmediate1,nextTick3,setImmediate2
,但我实际得到的是
nextTick1,nextTick2,setImmediate1,setImmedate2,nextTick3
然后我又开了一个测试来研究setImmediate()
的行为:
//the following code is using express as the framework
app.get('/test', function (req, res) {
res.end('The server is responding.');
});
app.get('/nexttick', function (req, res) {
function callback() {
process.nextTick(callback);
}
callback();
res.end('nextTick');
});
app.get('/setimmediate', function (req, res) {
function callback() {
setImmediate(callback);
}
callback();
res.end('setImmediate');
});
第1步:我在浏览器上访问了http://localhost:3000/nexttick
,我收到了文字nexttick
。
步骤2:我访问http://localhost:3000/test
以测试我的服务器是否仍在响应请求,并且我没有得到任何响应,浏览器一直在等待响应。这并不奇怪,因为process.nextTick()
的递归调用已经挂起了服务器。
Step3:我重启了服务器。
第4步:我访问了http://localhost:3000/setimmediate
并获得了文字setimmediate
步骤5:我再次访问http://localhost:3000/test
以测试我的服务器是否仍在响应。结果与Step2相同,我没有得到任何响应,浏览器一直在等待响应。
这意味着process.nextTick()
和setImmediate()
的行为几乎相同,但我知道它们不是。
我想知道为什么会发生这种情况或者我误解了某事。谢谢。
P.S。我在Windows 10下运行Node v0.12.7。
答案 0 :(得分:0)
实际上你的测试结果看起来不错(我只参考第一个测试)。 你的评论“setImmediate()只会在每个事件循环中执行一次。”是错的,见https://nodejs.org/api/timers.html#timers_setimmediate_callback_arg 这就是你不理解第一次测试结果的原因。
基本上,process.nextTick会将你的函数放在当前事件循环的末尾,而setImmediate会将它放在下一个事件循环中。
但是执行多个setImmediate是可以的,他们都将转到同一个下一个事件循环。
在
setImmediate(function() {
console.log('setImmediate1');
process.nextTick(function() {
console.log('nextTick3');
});
});
setImmediate(function() {
console.log('setImmediate2');
});
基本上你已经在下一个事件循环中调用了2个函数sthat,并且在其中一个中你放了另一个nextTick,它将在同一个循环结束时调用,但是在同一个循环结束时调用。 因此,它将首先调用那些2 setImmediate而不是第一个调用的nextTick。