Node.js事件循环

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

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


事件循环

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

涉及I / O呼叫的每个呼叫都需要您注册一个回叫。 此调用也会立即返回,这允许您在不使用应用程序代码中的线程的情况下并行执行多个IO操作。 只要I / O操作完成,它的回调就会被推送到事件循环中。 只要在执行之前在事件循环中推送的所有其他回调,它就会立即执行。

有几种方法可以对如何将回调添加到事件循环中进行基本操作。 通常你不应该需要这些,但时不时会有用。

  • setImmediate
  • process.nextTick
  • 在任何时候都不会有两条真正的并行执行路径,所以所有的操作本质上都是线程安全的。 通常会有多个由事件循环管理的异步并发执行路径。

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

    限制

    由于事件循环,节点不必为每个传入的tcp连接启动一个新的线程。 这允许节点同时服务数十万个请求,只要您不计算每个请求的前1000个质数。

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

    如果您想要执行CPU繁重的事情,您应该将它委派给另一个可以更有效地执行CPU绑定操作的进程,或者您可以将它作为节点本机添加进行编写。

    阅读更多关于用例的内容

    控制流

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

  • https://github.com/caolan/async
  • 我使用了回调,他们让我疯狂,我已经有了更好的使用Promise的经验,蓝鸟是一个非常受欢迎的快速承诺库:

  • https://github.com/petkaantonov/bluebird
  • 我发现这是节点社区中一个非常敏感的话题(回调与承诺),所以无论如何,使用你认为最适合你的方式。 一个好的控制流库也应该为你提供异步堆栈跟踪,这对于调试非常重要。

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

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

    我如何开始使用Node.js


    从威廉的回答:

    Node.js事件循环在单个线程下运行。 每个I / O呼叫都需要您注册一个回叫。 每个I / O调用也会立即返回,这允许您在不使用线程的情况下并行执行多个IO操作。

    我想开始用这个上面的引用来解释,这是我在任何地方都能看到的对js框架的常见误解之一。

    Node.js不会神奇地处理所有那些只有一个线程的异步调用,并且仍然保持该线程畅通。 它在内部使用谷歌的V8引擎和一个名为libuv(用c ++编写)的库,使它能够将一些潜在的异步工作委派给其他工作线程(类似于在那里等待任何要从主节点线程委派的工作的线程池) )。 然后,当那些线程完成它们的执行时,它们会调用它们的回调函数,这就是事件循环意识到工作线程的执行已完成的事实。

    nodejs的主要优点是你永远不需要关心这些内部线程,他们将远离你的代码! 所有通常应该在多线程环境中发生的令人讨厌的同步事件将由nodejs框架抽象出来,并且您可以在更加程序员友好的环境中愉快地处理单线程(主节点线程)(同时受益于多重性能的所有性能增强线程)。

    下面是一个很好的帖子,如果有人感兴趣:什么时候使用线程池?

    链接地址: http://www.djcxy.com/p/52671.html

    上一篇: Node.js Event loop

    下一篇: How is the 'use strict' statement interpreted in Node.js?