说说nodejs中的事件循环机制理解
# 是什么
事件循环: nodejs中异步队列里事件执行的机制,同浏览器的事件循环机制
基于libuv(多平台I/O库)实现
# 怎么用
# 六个阶段
记忆:tiipcc
- timer 执行setTimeout/setInterval的回调
- i/o 执行上一轮循环中未被执行的i/o回调
- idle 闲置阶段,系统内部调用
- poll 检查新的i/o事件,执行i/o回调
- check 检查阶段,setImmediate()回调函数在此执行
- close callback
一些关闭的回调函数, 如
socket.on('close')
每个阶段对应一个队列,当事件循环进入某个阶段时,将会在该阶段内执行回调,直到队列清空或者回调的最大值已经执行, 那么会进入到下一个阶段
# process.nextTick
插队者:不属于上述的任一阶段,是上一段进入下一段都会执行的一个特殊过渡
# 宏微任务
- 宏任务:setTimeout/setInterval/setImmediate/io事件/close事件
- 微任务: process.nextTick/Promise.then回调
执行过程,从上到下执行, 同步任务执行,异步任务根据类型放到分别的阶段, 等待同步任务执行完后--> nextTick--> 微任务 --> 宏任务
# 原理
# FAQ
async function async1() {
console.log('async1 start')
await async2()
console.log('async1 end')
}
async function async2() {
console.log('async2')
}
console.log('script start')
setTimeout(function () {
console.log('setTimeout0')
}, 0)
setTimeout(function () {
console.log('setTimeout2')
}, 300)
setImmediate(() => console.log('setImmediate'));
process.nextTick(() => console.log('nextTick1'));
async1();
process.nextTick(() => console.log('nextTick2'));
new Promise(function (resolve) {
console.log('promise1')
resolve();
console.log('promise2')
}).then(function () {
console.log('promise3')
})
console.log('script end')
点击查看
分析过程:
先找到同步任务,输出script start
遇到第一个 setTimeout,将里面的回调函数放到 timer 队列中
遇到第二个 setTimeout,300ms后将里面的回调函数放到 timer 队列中
遇到第一个setImmediate,将里面的回调函数放到 check 队列中
遇到第一个 nextTick,将其里面的回调函数放到本轮同步任务执行完毕后执行
执行 async1函数,输出 async1 start
执行 async2 函数,输出 async2,async2 后面的输出 async1 end进入微任务,等待下一轮的事件循环
遇到第二个,将其里面的回调函数放到本轮同步任务执行完毕后执行
遇到 new Promise,执行里面的立即执行函数,输出 promise1、promise2
then里面的回调函数进入微任务队列
遇到同步任务,输出 script end
执行下一轮回到函数,先依次输出 nextTick 的函数,分别是 nextTick1、nextTick2
然后执行微任务队列,依次输出 async1 end、promise3
执行timer 队列,依次输出 setTimeout0
接着执行 check 队列,依次输出 setImmediate
300ms后,timer 队列存在任务,执行输出 setTimeout2
script start async1 start async2 promise1 promise2 script end nextTick1 nextTick2 async1 end promise3 setTimeout0 setImmediate setTimeout2