一尘不染

Node.js事件循环

node.js

Node.js I / O事件循环是单线程还是多线程?

如果我有多个I / O进程,则节点会将它们置于外部事件循环中。它们是按顺序处理(最快),还是处理事件循环以同时处理它们(…以及哪些限制)?


阅读 291

收藏
2020-07-07

共1个答案

一尘不染

事件循环

Node.js事件循环在单个线程下运行,这意味着您编写的应用程序代码在单个线程上进行评估。Nodejs本身在libuv之下使用了许多线程,但是您在编写nodejs代码时不必处理那些线程。

每个涉及I / O调用的调用都要求您注册一个回调。该调用也会立即返回,这使您可以并行执行多个IO操作,而无需在应用程序代码中使用线程。一旦I /
O操作完成,它将在事件循环中推送其回调。一旦在事件上推送到该事件的所有其他回调都将被执行,它将立即执行。

有几种方法可以对将回调添加到事件循环中的方式进行基本操作。通常您不需要这些,但是有时它们会很有用。

任何时候都不会有两个真正的并行执行路径,因此所有操作本质上都是线程安全的。通常,事件循环将管理多个异步并发执行路径。

阅读有关事件循环的更多信息

局限性

由于事件循环,节点不必为每个传入的tcp连接都启动一个新线程。只要您不为每个请求计算前1000个素数,这就能使节点同时处理数十万个请求。

这也意味着不要执行CPU密集型操作,这一点很重要,因为这些操作将锁定事件循环并阻止其他异步执行路径继续执行。请勿使用sync所有I /
O方法的变体,这也很重要,因为这些方法也将锁定事件循环。

如果您想做大量的CPU工作,则应将其委托给另一个进程,该进程可以更有效地执行CPU绑定的操作,也可以将其编写为本机附加组件

阅读有关用例的更多信息

控制流

为了管理编写许多回调,您可能需要使用控制流库。我相信这是目前最流行的基于回调的库:

我曾经使用过回调,但它们几乎使我发疯,使用Promises时我有了更好的经验,bluebird是一个非常流行且快速的诺言库:

我发现这是节点社区(回调与Promise)中一个非常敏感的话题,因此,无论如何,请使用您认为适合自己的最佳方式。一个好的控制流库还应该为您提供异步堆栈跟踪,这对于调试非常重要。

事件循环中的最后一个回调完成它的执行路径并且不注册任何其他回调时,Node.js进程将完成。

这不是一个完整的解释,我建议您检查以下线程,它是最新的:

我如何开始使用Node.js

2020-07-07