大量异步操作
node中需要频繁的执行异步操作,获取异步结果。异步操作有两大类。
- 显式的异步代码。我们在程序里写的
process.nextTick()
、setTimeout()
等。 - 底层内核操作所产生的回调。node很多工作会传递给底层c++线程处理,得到结果后以回调的方式返回到nodeJs线程中。
事件循环
以事件循环的方式处理异步操作执行时机。事件循环含6个阶段,每个阶段内会处理该阶段所应执行的回调。
-
定时器阶段
处理setTimeou()
、setInterval()
所产生回调。上述两个函数产生的回调会在下次事件循环中调用。
-
待定回调阶段
此阶段对某些系统操作(如 TCP 错误类型)执行回调。
-
idle、prepare阶段
仅由系统内部使用。
-
轮询阶段
大部分回调会在此阶段执行,会根据任务产生相应的线程阻塞。阶段内会做三种事。
1.计算应该阻塞和轮询I/O的时间。
2.执行轮询队列中的事件。
3.轮询队列为空时。若有setImmediate()
调用,直接进入查询阶段。没有setImmediate()
调用时,会根据之前阶段所计算出的时间等待回调被加入队列,再执行。
4.轮询队列仍空时,会检查定时器是否触发,若定时器已准备就绪,就转至定时器阶段,执行定时器回调。
-
检查阶段
执行setImmediate()
回调。如上所述,setImmediate()
可使轮询阶段队列为空时,调到检查阶段,取消等待。
-
关闭回调阶段
处理关闭事件所产生的回调。
中间任务队列
上述六个阶段,处理绝大多数任务。还有一类任务不在上述阶段中处理,在阶段与阶段之间处理,为中间任务队列。分为nextTick队列和微任务队列。
- next队列
process.nextTick()
所产生的回调加入到next队列,在阶段之间执行。优先级大于微任务队列。 - 微任务队列
promise
状态变化产生回调函数加入到此。在nextTick执行后执行。
来源
nodeJs中文文档
大佬博客