事件循环
Node.js是单线程的语言,是通过事件循环处理非阻塞I/O操作的,Node会将这些操作转移到系统内核中,内核会在后台处理多种操作。当其中一个操作完成的时候,内核将通知Node将对应的回调函数加入轮询队列中。
Node的I/O处理使用了自己设计的基于事件驱动的跨平台抽象层libuv,它封装了不同操作系统的一些底层特性,对外提供统一的API,事件循环也是有libuv负责
Node中的每次事件循环都包含了6个阶段:
(1)timers阶段:这个阶段执行Timer(setTimeout
、setInterval
)的回调函数
(2)I/O回调阶段:执行一些系统调用错误的回调(比如网络通信的错误回调函数)
(3)idle,prepare阶段:仅供Node内部使用
(4)poll(轮询)阶段:获取新的I/O事件,执行I/O相关的回调函数,适当的条件下将Node阻塞在这里
(5)check阶段:执行setImmediate()
的回调函数
(6)close callbacks阶段:执行一些准备关闭的回调函数,比如执行Socket的close
事件回调
重点关注timers
、poll
和check
三个阶段,日常开发中的绝大部分异步任务都是在这三个阶段处理的。
timers
阶段
在这个阶段,Node会检查有无超时的Timer,如果有则把其回调函数压入timer的任务队列中等待执行。
同浏览器环境一样,Node并不能保证Timer在预设时间到了就会立即执行ÿ