每日前端夜话0x9F
每日前端夜话,陪你聊前端。
每天晚上18:00准时推送。
正文共:2277 字
预计阅读时间:10 分钟
作者:Piero Borrelli
翻译:疯狂的技术宅
来源:logrocket
Complete Guide To The Event Loop In Node.js
每当我听到人们谈论Node.js时,就会出现很多关于究竟是什么【https://nodejs.org/it/】,这项技术有什么用处,以及其未来的问题。
让我们试着解决第一部分。回答这个问题最简单的方法是列出许多 Node 技术上的定义:
但是,这些答案并不能令我满意,因为有些东西不见了。在读了上面的要点后,你可能会认为 Node.js 只是另一种 JavaScript 技术,但是如果你想要真正的理解它,最重要的是分析它是如何进行异步操作的和它的非阻塞 I/O 系统。
这是每个 Web 开发人员应该必备的知识。
准确的理解 Node 在幕后的工作原理,不仅会对这项技术了解的更多,还能够激发那些刚刚开始学习但还没深入使用的人们的兴趣。
对于已经是该领域的专业人士来说,了解它的内部和外部将使你成为一个全新、前沿的开发人员,可以根据你的需求去提高其性能。
因此,为了挖掘 Node 的世界,我们将检视其核心部分:事件循环,实际上它是负责其非阻塞 I/O 模型的部分。
在深入了解事件循环之前,我想先在线程上花一些时间。如果你想知道这样做的必要性,我会告诉你是为了更好地理解一个概念,我们必须先在自己的脑海中形成一个术语表,这将有助于我们识别系统的每一个部分。我们会在稍后阅读有关事件循环如何工作,以及如何将线程的概念应用于它的内容时,这最终将具有很大的优势。
每当我们运行一个程序时,就会为它创建一个实例,并且有一些内部调用线程与该实例相关。线程可以看作是我们的 CPU 必须执行的操作单元。许多不同的线程可以与程序的单个进程相关联。下面这个图可以帮你在脑海中形成这个想法:
了解线程
在讨论线程时最重要的一点是:我们的机器如何确定在什么时候处理哪个线程?
众所周知,我们机器的资源是有限的(CPU,RAM),因此正确的决定怎样分配它们是非常重要,换一种说法是,哪些操作优先于其他操作。这必须要做到,同时还要确操作不能消耗太多的时间 —— 没有人喜欢运行速度慢的电脑。
用于解决分配问题的机制称为 scheduling【https://www.tutorialspoint.com/operating_system/os_process_scheduling.htm】,它由操作系统中的调度程序管理。这背后的逻辑可能非常复杂,但总而言之,我们可以将执行此操作的两种主要方式组合在一起:
多核机器处理线程的方式
现在我们已经对线程如何工作有了基本的了解,接下来解决 Node.js 事件循环逻辑。通过本文,你将了解前面那些解释背后的原因,每一条都会对应到正确的位置上。
每当运行 Node 程序时,都会自动创建一个线程。这个线程是整个代码唯一执行的地方。在其中生成了一个被称为事件循环的东西。这个循环的作用是安排我们唯一的线程应该在什么时间点执行哪些操作。
现在让我们尝试模拟事件循环的工作原理及其工作方式。首先假设我们正在用名为 myProgram
的文件为 Node 提供信息,然后详细了解事件循环将对其进行的操作。
Feeding Node.js 示例文件
特别是,我将首用一个简短的图来解释,说明在事件循环 tick 过程中发生的事情,然后再以更深入的方式探讨这些阶段。
Node.js 事件循环的说明
不应该单纯的认为事件循环实际上是一个循环。它有一个特定的条件,用来确定循环是否需要再次迭代。事件循环的每次迭代都被称为一个 tick。
每当执行程序时,我们都会进行一系列需要执行的操作。这些操作主要分为三种类型:
setTimeout()
,setInterval()
,setImmediate()
)我稍后会详细介绍这些内容;现在让我们记住,只要其中一个操作处于挂起状态,事件循环就会执行一个新的 tick。
对于每个循环迭代,可以分为以下阶段:
setTimeout()
和 setInterval()
的回调函数是否准备好在计时器过期的情况下被调用。setImmediate()
函数相关函数。这是对 Node.js 的一种非常普遍的误解。Node 运行在单个线程上,但是 Node.js 标准库中包含的一些函数并不是(例如 fs
模块函数),他们的逻辑运行在 Node.js 线程之外。这样做是为了保证程序的速度和性能。
Node.js 会使用名为 libuv 的特殊库模块来执行异步操作。此库还与 Node 的后台逻辑一起使用,用来管理被称为 libuv 线程池 的特殊线程池。
这个线程池由四个线程组成,用于委派对事件循环来说太重的操作。长时间运行的任务对于事件循环而言代价过于昂贵。
从这个意义上说,虽然在上述过程中涉及一些类似栈的结构,但更精确的答案是事件循环由一系列的阶段所组成,每个阶段都有自己的特定任务,所有阶段都以循环重复的方式去处理。如果想要知道关于事件循环确切结构的更多信息,请查看此演讲【https://www.youtube.com/watch?v=PNa9OMajw9w】。
了解事件循环是使用 Node.js 的重要部分,无论你是想获得有关此技术的更多见解,了解如何提高其性能,还是找到学习新工具理由。
原文:https://blog.logrocket.com/a-complete-guide-to-the-node-js-event-loop/