”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > Node.js 中的事件循环如何工作?

Node.js 中的事件循环如何工作?

发布于2024-08-24
浏览:403

How event loop work in Node.js?

事件循环是 Node.js 中的一个核心概念,它使其能够有效地处理异步操作。以下是其工作原理的简化说明:

1. 单线程性质

Node.js 在单线程上运行。这意味着它一次只能执行一段代码。然而,Node.js 被设计为可以同时处理许多操作,而不需要多个线程。

2. 非阻塞I/O

Node.js 使用非阻塞 I/O 操作。当 Node.js 执行读取文件、查询数据库或发出网络请求等任务时,它不会等待这些任务完成就继续执行下一个任务。相反,它在处理这些任务时继续执行其他代码。

3. 事件循环机制

事件循环负责管理代码的执行和处理异步事件。它不断检查任务“队列”并决定执行哪些任务。这是一步一步的细分:

  • 初始化:当 Node.js 应用程序启动时,它会初始化并设置环境。
  • 执行阶段:Node.js 同步执行任何初始代码。如果存在异步任务(例如文件读取或 HTTP 请求),它们将被移交给系统的 API。
  • 事件循环阶段:事件循环有几个阶段,它按特定顺序处理每个阶段中的任务:
    • 定时器阶段:执行由setTimeout()和setInterval()安排的回调。
    • IO Callbacks Phase:执行I/O操作的回调,例如文件读取或网络请求。
    • 空闲,准备阶段:用于系统任务的内部阶段。
    • Poll Phase:检索新的 I/O 事件,执行它们的回调。如果poll队列为空,则会检查setImmediate()队列中是否有回调。
    • 检查阶段:执行setImmediate()安排的回调。
    • 关闭回调阶段:处理关闭事件,例如由socket.on('close').
    • 发出的事件
  • 重新检查并退出:如果事件循环没有更多任务要处理,它将退出,让程序终止。如果还有待处理的任务,它将继续运行。

4. 回调队列

异步任务完成后,将其回调推送到队列中。事件循环从队列中选取这些回调并按顺序执行它们。

5.微任务队列(下一个Tick)

除了主队列之外,还有一个微任务队列(或下一个滴答队列),其中使用 process.nextTick() 或 Promise 的 .then() 处理程序调度的回调排队。微任务优先于常规回调,这意味着它们在当前操作完成之后、事件循环进入下一阶段之前执行。

例子

下面是一个简单的例子来说明事件循环是如何工作的:

const fs = require('fs');

console.log('Start');

fs.readFile('file.txt', (err, data) => {
  if (err) throw err;
  console.log('File read complete');
});

console.log('End');

输出:

Start
End
File read complete

解释:

  1. console.log('开始');和 console.log('结束');同步执行。
  2. fs.readFile 发起异步文件读取操作,不等待继续执行下一行代码。
  3. 一旦文件读取操作完成,其回调(console.log('文件读取完成');)就会被推送到事件循环的回调队列中。
  4. 事件循环在同步代码执行完成后处理回调。

尽管 Node.js 是单线程的,但事件循环允许 Node.js 通过将操作委托给系统并异步处理其结果来有效地一次处理多个操作。

事件循环编排任务的执行,优先考虑微任务队列,以确保在继续执行主任务队列中的任务之前快速解决承诺和相关操作(宏任务)。

这种动态使 JavaScript 能够在单线程环境中处理复杂的异步行为。

版本声明 本文转载于:https://dev.to/syed_ammar/how-event-loop-work-in-nodejs-4lf4?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 我可以将加密从McRypt迁移到OpenSSL,并使用OpenSSL迁移MCRYPT加密数据?
    我可以将加密从McRypt迁移到OpenSSL,并使用OpenSSL迁移MCRYPT加密数据?
    将我的加密库从mcrypt升级到openssl 问题:是否可以将我的加密库从McRypt升级到OpenSSL?如果是这样,如何?答案:是的,可以将您的Encryption库从McRypt升级到OpenSSL。可以使用openssl。附加说明: [openssl_decrypt()函数要求iv参...
    编程 发布于2025-04-26
  • 如何在GO编译器中自定义编译优化?
    如何在GO编译器中自定义编译优化?
    在GO编译器中自定义编译优化 GO中的默认编译过程遵循特定的优化策略。 However, users may need to adjust these optimizations for specific requirements.Optimization Control in Go Compi...
    编程 发布于2025-04-26
  • 在Java中如何为PNG文件添加坐标轴和标签?
    在Java中如何为PNG文件添加坐标轴和标签?
    如何用java 在现有png映像中添加轴和标签的axes和labels如何注释png文件可能具有挑战性。与其尝试可能导致错误和不一致的修改,不如建议在图表创建过程中集成注释。使用JFReechArt import java.awt.color; 导入java.awt.eventqueue; 导入...
    编程 发布于2025-04-26
  • 如何使用Python理解有效地创建字典?
    如何使用Python理解有效地创建字典?
    在python中,词典综合提供了一种生成新词典的简洁方法。尽管它们与列表综合相似,但存在一些显着差异。与问题所暗示的不同,您无法为钥匙创建字典理解。您必须明确指定键和值。 For example:d = {n: n**2 for n in range(5)}This creates a dicti...
    编程 发布于2025-04-26
  • Python中何时用"try"而非"if"检测变量值?
    Python中何时用"try"而非"if"检测变量值?
    使用“ try“ vs.” if”来测试python 在python中的变量值,在某些情况下,您可能需要在处理之前检查变量是否具有值。在使用“如果”或“ try”构建体之间决定。“ if” constructs result = function() 如果结果: 对于结果: ...
    编程 发布于2025-04-26
  • 如何实时捕获和流媒体以进行聊天机器人命令执行?
    如何实时捕获和流媒体以进行聊天机器人命令执行?
    在开发能够执行命令的chatbots的领域中,实时从命令执行实时捕获Stdout,一个常见的需求是能够检索和显示标准输出(stdout)在cath cath cant cant cant cant cant cant cant cant interfaces in Chate cant inter...
    编程 发布于2025-04-26
  • 为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    使用php dateTime修改月份:发现预期的行为在使用PHP的DateTime类时,添加或减去几个月可能并不总是会产生预期的结果。正如文档所警告的那样,“当心”这些操作的“不像看起来那样直观。 考虑文档中给出的示例:这是内部发生的事情: 现在在3月3日添加另一个月,因为2月在2001年只有2...
    编程 发布于2025-04-26
  • 在Ubuntu/linux上安装mysql-python时,如何修复\“ mysql_config \”错误?
    在Ubuntu/linux上安装mysql-python时,如何修复\“ mysql_config \”错误?
    mysql-python安装错误:“ mysql_config找不到”“ 由于缺少MySQL开发库而出现此错误。解决此问题,建议在Ubuntu上使用该分发的存储库。使用以下命令安装Python-MysqldB: sudo apt-get安装python-mysqldb sudo pip in...
    编程 发布于2025-04-26
  • 如何正确使用与PDO参数的查询一样?
    如何正确使用与PDO参数的查询一样?
    在pdo 中使用类似QUERIES在PDO中的Queries时,您可能会遇到类似疑问中描述的问题:此查询也可能不会返回结果,即使$ var1和$ var2包含有效的搜索词。错误在于不正确包含%符号。通过将变量包含在$ params数组中的%符号中,您确保将%字符正确替换到查询中。没有此修改,PDO...
    编程 发布于2025-04-26
  • 解决MySQL错误1153:数据包超出'max_allowed_packet'限制
    解决MySQL错误1153:数据包超出'max_allowed_packet'限制
    mysql错误1153:故障排除比“ max_allowed_pa​​cket” bytes 更大的数据包,用于面对阴谋mysql错误1153,同时导入数据capase doft a Database dust?让我们深入研究罪魁祸首并探索解决方案以纠正此问题。理解错误此错误表明在导入过程中接...
    编程 发布于2025-04-26
  • 如何在其容器中为DIV创建平滑的左右CSS动画?
    如何在其容器中为DIV创建平滑的左右CSS动画?
    通用CSS动画,用于左右运动 ,我们将探索创建一个通用的CSS动画,以向左和右移动DIV,从而到达其容器的边缘。该动画可以应用于具有绝对定位的任何div,无论其未知长度如何。问题:使用左直接导致瞬时消失 更加流畅的解决方案:混合转换和左 [并实现平稳的,线性的运动,我们介绍了线性的转换。这...
    编程 发布于2025-04-26
  • 如何在鼠标单击时编程选择DIV中的所有文本?
    如何在鼠标单击时编程选择DIV中的所有文本?
    在鼠标上选择div文本单击带有文本内容,用户如何使用单个鼠标单击单击div中的整个文本?这允许用户轻松拖放所选的文本或直接复制它。 在单个鼠标上单击的div元素中选择文本,您可以使用以下Javascript函数: function selecttext(canduterid){ if(do...
    编程 发布于2025-04-26
  • 如何使用PHP从XML文件中有效地检索属性值?
    如何使用PHP从XML文件中有效地检索属性值?
    从php $xml = simplexml_load_file($file); foreach ($xml->Var[0]->attributes() as $attributeName => $attributeValue) { echo $attributeName,...
    编程 发布于2025-04-26
  • 如何简化PHP中的JSON解析以获取多维阵列?
    如何简化PHP中的JSON解析以获取多维阵列?
    php 试图在PHP中解析JSON数据的JSON可能具有挑战性,尤其是在处理多维数组时。要简化过程,建议将JSON作为数组而不是对象解析。执行此操作,将JSON_DECODE函数与第二个参数设置为true:[&&&&& && &&&&& json = JSON = JSON_DECODE($ j...
    编程 发布于2025-04-26
  • 为什么我在Silverlight Linq查询中获得“无法找到查询模式的实现”错误?
    为什么我在Silverlight Linq查询中获得“无法找到查询模式的实现”错误?
    查询模式实现缺失:解决“无法找到”错误在Silverlight应用程序中,尝试使用LINQ建立LINQ连接以错误而实现的数据库”,无法找到查询模式的实现。”当省略LINQ名称空间或查询类型缺少IEnumerable 实现时,通常会发生此错误。 解决问题来验证该类型的质量是至关重要的。在此特定实例中...
    编程 发布于2025-04-26

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3