1. 三大关键阶段
- 执行定时器回调的阶段。检查定时器,如果到了时间,就执行回调。这些定时器就是 setTimeout、setInterval。
轮询(英文叫 poll)阶段。因为在 node 代码中难免会有异步操作,比如文件I/O,网络I/O等等,那么当这些异步操作做完了。就会来通知主线程,怎么通知呢?就是通过‘data’、'connect'等事件使得时间循环到达 poll 阶段。到达了这个阶段后:
如果当前已经存在定时器,而且有定时器到时间了,拿出来执行,eventLoop 将回到 timer 阶段。
如果没有定时器,就会去看回调函数队列。
- 如果队列不为空,拿出队列中的方法依次执行;
- 如果队列为空,检查是否有 setImmdiate 的回调
- 有则前往 check 阶段;
- 没有则继续等待,相当于阻塞了一段时间(阻塞时间是有上限的),等待 callback 函数加入队列,加入后会立刻执行。一段时间后自动进入 check 阶段。
check 阶段。这是一个比较简单的阶段,直接执行 setImmdiate 的回调。
2.完善
- timer 阶段;
- I/O 异常回调阶段;
- 空闲、预备状态(第二阶段结束,poll 未触发之前)
- poll 阶段;
- check 阶段
- 关闭时间的回调阶段
3. nodejs 和浏览器关于 eventLoop 的主要区别
两者最主要的区别在于浏览器中的微任务是在每个相应的宏任务中执行的,而 nodejs 中的微任务是在不同阶段执行的
process.nextTick
process.nextTick 是一个独立于 eventLoop 的任务队列。
在每一个 eventLoop 阶段完成后回去检查这个队列,如果里面有任务,会让这部分任务优先于微任务执行;