可以这样来理解. process.nextTick和setImmediate方法在实现上分别对应这两个队列-- 不妨叫作nextTick队列和immediate队列. 到nextTick的时候, 这两个队列被执行的情况有所差异: nextTick队列中的方法会被全部执行(包括在执行过程中新加的),而immediate队列只会取其第一个方法来执行.
function nextTick(msg, cb) {
process.nextTick(function() {
console.log('tick: ' + msg);
if (cb) {
cb();
}
});
}
function immediate(msg, cb) {
setImmediate(function() {
console.log('immediate : ' + msg);
if (cb) {
cb();
}
});
}
nextTick('1');
nextTick('2', function() {
nextTick('10');
});
immediate('3', function() {
nextTick('5');
});
nextTick('7', function() {
immediate('9');
});
immediate('4', function() {
nextTick('8');
});
这段代码的输出是:
tick: 1
tick: 2
tick: 7
tick: 10
immediate : 3
tick: 5
immediate : 4
tick: 8
immediate : 9
解释如下:
1). 第一遍执行时, 会分别向nextTick队列和immedidate队列中加入方法,它们变成:
nextTick: 1 2 7 数字代表输出相应数字的那个nextTick方法对应的callback方法,下同
immedidate: 3 4
2). 到了nextTick, 开始执行回调
先执行 nextTick 队列中的回调(全部执行才结束):
2.1) 执行1 -- 输出1, nextTick队列变为 2 7
2.2) 执行 2 -- 输出2, 并向nextTick队列添加10, nextTick队列变为 7, 10
2.3) 执行7 -- 输出7, 并向immediate队列添加9. nextTick 队列变为 10, immediate队列变为 3 4 9
2.4) nextTick 队列中还有一个新添加的10, 故执行它, 输出10
再执行 immediate队列的第一个回调方法(immediate队列为 3 4 9), 即执行3. 3的执行,输出3同时向nextTick队列中加入5 --- 5 不会在这个tick执行, 因为本轮nextTick的执行已经结束了. 此时, 队列变为:
nextTick: 5
immedidate: 4 9
这也是进入下一轮tick前的队列状态.
3). 到了nextTick, 开始执行回调
队列为:
nextTick: 5
immedidate: 4 9
和上一轮类似:
3.1) 执行 nextTick 5, 输出 5. nextTick为空, 执行完毕.
执行immediate队列的第一个回调, 即4, 输出4, 并向nextTick队列加入8. 此时队列变化为:
nextTick: 8
immediate: 9
4). 到了nextTick, 开始执行回调
根据上述原理,不难知道 将分别执行 nextTick 8 和 immediate 9 , 将输出8和输出9.