Node.js 的 EventLoop 是什么?
背景知识
Node.js 将各种函数(也叫任务或回调)分成至少 6 类,按先后顺序调用,因此将时间分为六个阶段:
timer 阶段(setTimeout)
I/O callbacks 该阶段不用管
idle,prepare 该阶段不用管
poll 轮询阶段,停留时间最长,可以随时离开
check 阶段,主要处理 setImmediate 任务
close callback 该阶段不用管
Node.js 会不停的从 1 ~ 6 循环处理各种事件,这个过程叫做事件循环(Event Loop)。
nextTick
process.nextTick(fn) 的 fn 会在什么时候执行呢?
在 Node.js 11 之前,会在每个阶段的末尾集中
执行(俗称队尾执行)。
在 Node.js 11 之后,会在每个阶段的任务间隙
执行(俗称插队执行)。
浏览器跟 Node.js 11 之后的情况类似。可以用 window.queueMicrotask 模拟 nextTick。
Promise
Promise.resolve(1).then(fn) 的 fn 会在什么时候执行?
这要看 Promise 源码是如何实现的,一般都是用 process.nextTick(fn) 实现的,所以直接参考 nextTick。
async / await
这是 Promise 的语法糖,所以直接转为 Promise 写法即可。
面试题 1:
setTimeout(() => {
console.log('setTimeout')
})
setImmediate(() => {
console.log('setImmediate')
})
// 在 Node.js 运行会输出什么?
// A setT setIm
// B setIm setT
// C 出错
// D A 或 B
// 在浏览器执行会怎样?
//A 或 B
面试题 2:
async function async1(){
console.log('1')
async2().then(()=>{
console.log('2')
})
}
async function async2(){
console.log('3')
}
console.log('4')
setTimeout(function(){
console.log('5')
},0)
async1();
new Promise(function(resolve){
console.log('6')
resolve();
}).then(function(){
console.log('7')
})
console.log('8')
微任务队列(间隙插队):async2#then、promise#then
宏任务对列(最后执行):setTimeout
最终执行:4 1 3 6 8 后面为异步队列 2(async2#then) 7(omise#then) 5(setTimeout)