我对nextTick和setImmediate之间的差异感到非常困惑.我已经在互联网上阅读了有关它们的所有文档,但我仍然不明白它们是如何工作的.
例子:
function log(n) { console.log(n); }
Run Code Online (Sandbox Code Playgroud)
setImmediate
setImmediate(function() {
setImmediate(function() {
log(1);
setImmediate(function() { log(2); });
setImmediate(function() { log(3); });
});
setImmediate(function() {
log(4);
setImmediate(function() { log(5); });
setImmediate(function() { log(6); });
});
});
//1 2 3 4 5 6
Run Code Online (Sandbox Code Playgroud)
nextTick
process.nextTick(function() {
process.nextTick(function() {
log(1);
process.nextTick(function() { log(2); });
process.nextTick(function() { log(3); });
});
process.nextTick(function() {
log(4);
process.nextTick(function() { log(5); });
process.nextTick(function() { log(6); });
});
});
//1 4 2 3 5 6
Run Code Online (Sandbox Code Playgroud)
为什么这些结果?请用视觉或非常容易理解的方式解释.甚至节点核心开发人员也不同意人们应该如何理解nextTick和setImmediate.
资料来源:
Dav*_*any 102
考虑以下两个例子:
setImmediate
setImmediate(function A() {
setImmediate(function B() {
log(1);
setImmediate(function D() { log(2); });
setImmediate(function E() { log(3); });
});
setImmediate(function C() {
log(4);
setImmediate(function F() { log(5); });
setImmediate(function G() { log(6); });
});
});
setTimeout(function timeout() {
console.log('TIMEOUT FIRED');
}, 0)
// 'TIMEOUT FIRED' 1 4 2 3 5 6
// OR
// 1 'TIMEOUT FIRED' 4 2 3 5 6
Run Code Online (Sandbox Code Playgroud)
nextTick
process.nextTick(function A() {
process.nextTick(function B() {
log(1);
process.nextTick(function D() { log(2); });
process.nextTick(function E() { log(3); });
});
process.nextTick(function C() {
log(4);
process.nextTick(function F() { log(5); });
process.nextTick(function G() { log(6); });
});
});
setTimeout(function timeout() {
console.log('TIMEOUT FIRED');
}, 0)
// 1 4 2 3 5 6 'TIMEOUT FIRED'
Run Code Online (Sandbox Code Playgroud)
setImmediate回调是在事件循环中触发的,每次迭代按照它们排队的顺序触发一次.因此,在事件循环的第一次迭代中,将触发回调A. 然后在事件循环的第二次迭代中,触发回调B,然后在事件循环的第三次迭代中触发回调C等.这可以防止事件循环被阻塞并允许其他I/O或计时器回调在平均时间内调用(就像0ms超时的情况一样,在第一次或第二次循环迭代时触发).
但是,nextTick回调总是在当前代码执行完毕后立即触发,并且在返回事件循环之前.在nextTick示例中,我们在返回事件循环之前最终执行所有nextTick回调.由于将从事件循环中调用setTimeout的回调,因此在我们完成每个nextTick回调之前,不会输出文本'TIMEOUT FIRED'.
gsa*_*edo 23
根据Node.js doc这两个函数的名称是完全交换的
setImmediate()(推荐最佳)
它首先在事件队列中着火
process.nextTick()(特殊情况的使用见后面的例子)
它立即起火了,它有点在当前文件的末尾写一个声明
如果我们有这个代码
setTimeout(function(){
console.log('Hello world 5'); // It's waiting like a normal person at a queue
}, 0);
setImmediate(function(){
console.log('Hello world 4');
// It's like get to last and be take care of first
// but always after of .nextTick and before of setInterval(, 0)
});
process.nextTick(function(){
console.log('Hello world 3'); // It's like be at the bottom at this file
});
console.log('Hello world 1');
console.log('Hello world 2');
Run Code Online (Sandbox Code Playgroud)
根据您的要求进行直观说明:
使用process.nextTick()的情况,在处理它之前必须发出和事件:
const EventEmitter = require('events');
const util = require('util');
function MyEmitter() {
EventEmitter.call(this);
// use nextTick to emit the event once a handler is assigned
process.nextTick(function () {
this.emit('event');
}.bind(this));
}
util.inherits(MyEmitter, EventEmitter);
const myEmitter = new MyEmitter();
myEmitter.on('event', function() {
console.log('an event occurred!');
});
Run Code Online (Sandbox Code Playgroud)
看看这个视频菲利普罗伯茨给我们一个关于运行时事件循环的一个很好的解释,看看这个在线eventloop调试器实时测试事件循环如何工作
资料来源:https: //github.com/nodejs/node/blob/master/doc/topics/the-event-loop-timers-and-nexttick.md#processnexttick-vs-setimmediate
下面让您更清楚。
require. console.log("I'm First");
setImmediate(function () {
console.log('Im setImmediate');
});
console.log("I'm Second");
process.nextTick(function () {
console.log('Im nextTick');
});
console.log("I'm Last");
/*
Output
$ node server.js
I'm First
I'm Second
I'm Last
Im nextTick
Im setImmediate
*/
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
25789 次 |
| 最近记录: |