gpt4 book ai didi

node.js - Node.js 执行程序需要哪些步骤?

转载 作者:太空宇宙 更新时间:2023-11-03 22:47:34 27 4
gpt4 key购买 nike

我已经探索node.js有一段时间了。但还没有确切地弄清楚程序是如何执行的。

例如采用这个简单的程序:

// file app.js`

var fs = require('fs');

var fileBuffer = fs.readFileSync('./sample.txt');

fs.readFile('./resource.json', function (er, data) {
console.log(data);
});

console.log(fileBuffer);

现在,当我们输入 node app.js(在命令行上)时,幕后会发生什么,直到程序结束。

具体来说,我想了解:

  1. 事件循环如何处理前两个阻塞 I/O 调用;以及;
  2. 关于异步。函数,一旦 I/O 完成,它发送到事件队列的内容以及如何以及何时调用附加的回调。

最佳答案

阻塞 I/O 就是这样:调用在完成之前不会返回。所以当你调用readFileSync时,它直接调用操作系统 API 来读入文件,并且仅当整个内容已复制到 Buffer 中时。控制返回给你的 JS。

对于阻塞(同步)函数,事件循环与 I/O 的处理方式完全无关。这就是同步 I/O 在 Node 中非常糟糕的原因——它会阻止任何其他事情发生,因为事件循环没有运行。

另一方面,普通(异步)I/O 函数如 readFile只需输入要完成的 I/O 请求,然后返回即可。 I/O 的具体执行方式取决于 I/O 请求的性质(即文件系统还是网络),但它全部由 C 库处理 libuv在单独的线程上。

  • 网络 I/O 实际上是使用主机操作系统的 native asynchronous 执行的。 I/O facilities ,它非常快,并且不需要为每个连接使用单独的线程。

    每当操作系统报告网络 I/O 事件时,该事件就会被放入队列中。在事件循环的下一个周期,事件被拾取并分派(dispatch)到适当的 JavaScript 函数。 (C代码可以获取JS函数的引用并调用它们。)

  • 文件 I/O 是使用正常的阻塞系统 I/O 调用完成的。每个 I/O 请求都放在 libuv work queue 中并由线程池执行。这里的关键是阻塞 I/O 是在 C 语言中完成的,在与 JavaScript 线程分开的线程上。

    当阻塞 I/O 调用返回时,结果将被放入队列中。同样,该事件将在下一个时钟周期内调度。

Node 保留待处理工作请求的引用计数——例如 I/O、计时器和监听服务器。如果在一个刻度结束时有零,则该过程退出。 (在某些情况下,您可以使用 unref() 显式从引用计数中删除事件请求。)

其他一些相关答案将有助于进一步解释其中一些概念:

<小时/>

最后,让我们看一下您的示例程序。实际发生的情况如下:

  • require('fs')为您提供对已初始化的 fs 模块的引用。内置模块比较特殊,不需要 I/O 加载。
  • fs.readFileSync调用操作系统文件 API。直到文件内容复制到内存中才会返回。
  • fs.readFile将一个项目(包含文件名和回调的引用)添加到 libuv 工作队列,然后立即返回。 (因为工作队列上没有任何内容,所以 I/O 将很快在单独的线程上开始。)
  • fileBuffer的内容已记录到控制台。
  • 此时,控制到达程序末尾,因此它返回到 Node 。这是第一个刻度的结束。由于存在挂起的 I/O, Node 不会退出。
  • Node 进入“空闲”状态。事件循环在无限循环中检查事件队列中是否有新项目。许多蜱虫经过,直到...
  • 异步 I/O 操作最终完成并将结果添加到事件队列中。下一个刻度会将事件从队列中弹出,并调用您最初传递给 readFile 的回调函数。 .
  • data的内容记录到控制台并且回调函数返回。
  • 时间已结束,不再有待处理的工作。 Node 退出。

关于node.js - Node.js 执行程序需要哪些步骤?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22847406/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com