原文=> What you should know to really understand the Node.js Event Loop
Node.js 是一个基于事件的平台。这就意味着在Node中发生的所有事情都是对事件的反应。在 Node 中调用是通过一系列回调完成的。
在开发者看来,这一切都由一个名为 libuv 的库处理,它提供了一种称为事件循环的机制。
事件循环机制也许是在整个环境中最被误解的概念
常见的误解
误解1:时间循环和用户代码跑在不同的线程当中
原因:用户的代码跑在主线程中,事件循环则在另外一个线程,每次执行回调,主线程将工作交给事件循环完成,然后事件循环将 ping 主线程进行回调
真实的:只有一个线程在执行 JS 代码,这个线程就是事件循环运行的线程。
执行回调(知道正在运行的node.js应用程序中的每个用户级代码都是回调)由事件循环完成。我们稍后会深入讨论这一点。
误解2:所有异步事件都由线程池处理
原因:异步操作(如使用文件系统)执行出站 HTTP 请求或与数据库交谈始终加载到由 libuv 提供的线程池。
真实的:默认情况下,libuv创建一个包含四个线程的线程池,以将异步工作分流。如今的操作系统已经为许多I / O任务提供了异步接口(例如 Linux 的 aio)。只要有可能,libuv就会使用这些异步接口,避免使用线程池。这同样适用于数据库等第三方子系统。在这里,驱动程序的作者宁愿使用异步接口,而不使用线程池。简而言之:只有在没有其他方式时,线程池才会用于异步I / O。
误解3:事件循环就像堆栈或者队列一样
原因:事件循环不断在遍历一系列异步任务,并在任务完成时执行回调
真实的:虽然涉及到队列式结构,但事件循环不会贯穿并处理堆栈。事件循环作为一个过程是一组阶段,其中包含以循环方式处理的特定任务。
了解事件循环的生命周期
要真正了解事件循环,应该清楚各个工作分别在那个阶段完成了任务。下图将会展示事件循环是如何工作的
具体请前往 => The Node.js Event Loop,Timers,and process.nextTick() | Node.js
计时器
通过 setTimeout() 或 setInterval() 计划的所有内容都将在此处理。
IO 回调
在这里所有的回调都会被处理。由于 node 中所有业务代码都是基于回调的。(例如,对传入http请求的回调触发级联回调),因此这是处理业务代码的阶段。
IO 轮询
投票处理下一次处理的新事件
立即设置
运行通过 setImmediate() 注册的所有回调
关闭
执行所有的 (‘close’) 回调
工作处理延迟
此度量标准测量线程池处理异步任务需要多长时间。高工作时间处理延迟表明繁忙/耗尽的线程池。