面试题
console.log('1');
setTimeout(function() {
console.log('2');
process.nextTick(function() {
console.log('3');
});
new Promise(function(resolve) {
console.log('4');
resolve();
}).then(function() {
console.log('5');
});
});
process.nextTick(function() {
console.log('6');
});
new Promise(function(resolve) {
console.log('7');
resolve();
}).then(function() {
console.log('8');
});
setTimeout(function() {
console.log('9');
process.nextTick(function() {
console.log('10');
})
new Promise(function(resolve) {
console.log('11');
resolve();
}).then(function() {
console.log('12')
});
})
答案
1、7、6、8、2、4、9、11、3、10、5、12
解析
常规的 JS 事件循环机制就不多介绍了,解析的重点是里面用到了 process.nextTick()
方法,说明是在 node 环境下。
node 环境下的事件循环中的宏任务和浏览器的有点不一样,node 中的宏任务呗分成了几种不同的阶段:
setTimeout
和setInterval
属于 timers 阶段setImmdiate
属于 check 阶段socket.on('close', ...)
的关闭事件属于 close callbacks 阶段- 其他所有的宏任务都属于 poll 阶段
node 中只要执行到某个阶段,就会执行完该阶段的所有任务。
浏览器下,是在每个宏任务执行完后,接着清空微任务队列,然后才会执行下一个宏任务。
而 node 的 process.nextTick()
会在每个阶段的后面执行,但是会优先于微任务。
具体流程如图: