Nodejs 中的“异步 I/O 原语”是什么意思?

Siv*_*han 6 node.js

我正在浏览 Node.js 文档,但无法理解这一行:

Node.js 应用程序在单个进程中运行,无需为每个请求创建新线程。Node.js 在其标准库中提供了一组异步 I/O 原语,可防止 JavaScript 代码阻塞,并且通常 Node.js 中的库是使用非阻塞范例编写的,这使得阻塞行为成为例外而不是常态。

来源:node.js 简介

具体我没能理解:

[...]Node.js 在其标准库中提供了一组异步 I/O 原语,可防止 JavaScript 代码阻塞 [...]

这是否仅仅意味着它具有内置功能,可以提供异步工作的功能?如果不是,那么这些异步 I/O 原语集是什么?如果有人可以为我提供一些链接以更好地理解或开始使用 Node.js,那就太好了。

PS:我有 Nodejs 的实践经验,我了解它的代码如何工作,但不明白它为什么会工作,所以我想了解它的理论部分,这样我就可以了解后台实际发生的事情。

Joa*_*uer 6

这是否仅仅意味着它具有内置功能,可以提供异步工作的功能?

是的,基本上就是这个意思。

在“传统”每个连接一个线程*模型中,您接受一个连接,然后将该请求的处理交给一个线程(无论是新启动的线程还是来自池,实际上并没有太大变化)并执行以下操作:与该线程上的该连接相关的所有工作,包括发送响应。

这可以通过同步/阻塞 I/O 轻松完成:有一个read简单返回读取字节的方法和一个write阻塞直到写入完成的方法。

然而,这确实意味着处理该请求的线程不能执行任何其他操作,并且您需要许多线程才能处理许多并发连接/请求。由于 I/O 操作需要相对较长的时间(以内存访问和计算的速度来衡量),这意味着大多数线程将在大部分时间等待一个或另一个 I/O 操作。

拥有异步 I/O 和基于事件的核心架构意味着,当启动 I/O 操作时,CPU 可以立即继续处理下一步需要执行的任何操作,这可能与完全不同的请求相关。

因此,可以在单个线程上处理更多请求。

“原语”仅意味着基本 I/O 操作(例如往返网络连接或文件的“读取字节”和“写入字节”)作为异步操作提供,并且需要在这些操作之上构建更高级别的操作(同样)以异步方式,保持优势)。

顺便说一句:许多其他编程环境要么很早就拥有异步 I/O API,要么是最近几年才获得的。Node.js 与众不同的一件事是它是默认选项:如果您从套接字或文件读取,那么异步执行就是“正常”的,而阻塞调用是一个很大的例外。这意味着围绕 Node.js 的整个生态系统(即几乎所有第三方库)都遵循这一假设,并且也以相同的方式编写。

因此,虽然 Java 具有异步 I/O,但一旦您使用任何仅支持阻塞 I/O 的 I/O 相关库,您就会失去该优势。

* 假设每个连接都包含一个请求,我在此答案中可互换地使用连接/请求。如今,这种假设通常是错误的(最常见的协议允许在单个连接中存在多个请求/响应对),但是在单个连接上处理多个请求并不会从根本上改变这个答案。


小智 0

这意味着 Node js 不会因输入/输出操作而停止。假设您需要执行某些任务并且它有一些阻塞条件,例如,如果按下空格键,则执行此操作,或者在未按下 esc 键时继续接受输入,因为节点 js 是单线程的,这将停止所有操作,并且它将专注于执行操作阻塞条件作业直到其完成为止,异步将允许应用程序在执行一项任务时不会停止其他任务,它会执行其他任务,直到任务完成,这就是为什么我们在处理数据时使用 wait 从 Node js 异步函数中的 Promise 中获取值然后指针将到达await行所在的行并从中获取值或处理信息。