node.js - Node.js 中单线程如何处理异步代码?

标签 node.js

我想知道即使回调已经完成。如果 Node 是单线程模型,主线程上的回调和其他进程如何并行执行。

最佳答案

首先,回调不是并行执行的。一次只有一个 Javascript 执行线程,因此 Javascript 代码不存在实际的并行执行。您可以同时进行多个异步 native 代码操作,但是当它们需要运行某种 Javascript 完成回调时,这些操作一次运行一个,而不是并行运行。

Javascript 是一种事件驱动语言,这意味着计时器、异步磁盘 I/O 回调、网络操作回调等......都使用事件队列。当 JS 引擎完成执行一段 Javascript 并将控制权返回给系统时,JS 引擎会从事件队列中取出下一个事件并执行它。 native 代码操作可以通过将事件插入事件队列来表明它们已完成并希望运行回调。

对于像 HTTP 请求这样的异步操作,例如 http.get(),基本上会发生以下情况:

  1. 您的 JavaScript 调用 http.get()
  2. 该调用发送 http 请求,然后立即返回。无论您传递给 http.get() 的回调是什么,都由 http 模块内部存储,并与特定的网络请求关联。
  3. http.get() 之后的 JavaScript 代码将继续执行,直到完成并将控制权返回给系统。
  4. 然后,一段时间后,上一个 HTTP 请求的响应返回到 TCP 引擎。这会导致 http 模块在 Javascript 事件队列中插入一个事件,以调用您之前使用 http.get() 发送的完成回调。
  5. 如果 Javascript 引擎当前没有执行任何其他操作,则会执行您的回调并传递结果响应数据。
  6. 如果 Javascript 引擎此时正在执行某些操作,则该事件将位于事件队列中,直到当前正在执行的 Javascript 片段完成并将控制权返回给系统。此时,JS 引擎会检查事件队列,并将下一个事件从队列中拉出并执行。如果这是您的回调,那么您的回调将在此时被调用。

因此,各种操作(例如异步磁盘 I/O、网络操作等)可以在后台运行,因为它们是由 native 代码(而不是 Javascript 引擎)控制的。如果需要, native 代码能够使用线程。 fs 模块使用线程,而 net 模块则不使用线程,因为 native 操作系统已经支持异步网络操作。

关于node.js - Node.js 中单线程如何处理异步代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41738661/

相关文章:

javascript - mongoose 不通过 ID 更新模型

node.js - 如何在Windows上通过crontab或cron作业运行Shell脚本

node.js - 如何让机器人启动1 :1 conversation in a group with the user in Slack using Microsoft bot-framework?

node.js - 更改TypeScript OutDir断点后,再也不会命中

node.js - 在 Azure Web App 中访问 SSL 证书

javascript - 如何对需要其他模块的 Node.js 模块进行单元测试以及如何模拟全局 require 函数?

javascript - 我将如何使用 Socket-IO 上传图像文件?

node.js - Query() DynamoDB 查询 Lambda NodeJS 上数组中的每个值

node.js - 如何卸载从 pkg (Mac OS X) 安装的 nodejs?

javascript - 如何在 Node.js 中为 JWT 设置 Cookie