【问题标题】:Why is async programming needed in NodeJS?为什么 NodeJS 需要异步编程?
【发布时间】:2023-04-10 18:01:01
【问题描述】:
我对 NodeJS 中的 async 概念有疑问。我已经阅读了很多关于 NodeJS 中的事件轮询的内容。他们会说:
事件循环允许 Node.js 执行非阻塞 I/O
操作
或
Node 使用 Worker Pool 来处理“昂贵”的任务。这包括
操作系统不为其提供非阻塞的 I/O
版本,以及 CPU 密集型任务。
或
这些是使用此工作池的 Node 模块 API,例如
作为文件系统(fs)
所以,我发现 Node 使用线程池来管理运行的 I/O。现在我的问题是,如果 Node 正在管理它们,为什么我们需要在 NodeJS 中使用async programming? BlueBird 等模块背后的原因是什么?
【问题讨论】:
标签:
node.js
asynchronous
threadpool
【解决方案1】:
tl;dr:您需要async 来防止阻塞事件循环。
NodeJS 使用一定数量的线程来处理客户端。基本上有两种类型的线程:
事件循环:
基本上需要异步编程的原因:
一旦注册了所有事件,NodeJS 就会进入事件循环并处理所有传入请求以及传出响应。它们都通过事件循环。
工作池
如您所说,NodeJS 使用 Worker Pool 来执行 I/O 和 CPU 密集型任务。
异步代码
为了防止阻塞主线程,您希望保持事件循环干净,并委派某些任务。这是需要异步代码的地方。这样你的代码就变得非阻塞了。不过,关于异步和非阻塞的术语有点模糊。澄清一下:
-
异步代码:并行执行某些任务
-
非阻塞:基本上轮询而不阻塞进一步的代码。
然而,在 NodeJS 中,异步通常用于 I/O 操作。它不仅仅意味着“并行执行”,因为它主要意味着“不要阻塞并获取信号”。
所以为了让 NodeJS 的 Event Loop 高效,我们不想等待一个操作完成。因此我们注册了一个异步“监听器”。这让 NodeJS 能够有效地管理自己的资源。
BlueBird(或一般的 Promise):
您提到的 BlueBird 之类的库不再需要,因为 NodeJS 支持开箱即用的承诺(请参阅注释 here)。
Promise 只是编写异步代码的另一种方式。 Async/Await 和 Generator Functions 也是如此。
旁注:使用 async 关键字定义的函数实际上会产生一个承诺。