这是我之前的问题Node.js Non Blocking Nature. 我仍然无法完全理解 Node.js 发生了什么。假设 Node 收到了来自用户的大文件上传请求。现在我们说我们将处理文件的代码放在回调中,从而使其异步。接下来发生什么 ?假设回调被放入 Node.js 应用程序需要处理的大量事件列表中,到目前为止它还没有阻塞。但是在某些时候,回调会从事件循环中拉出,并且它的代码开始运行(上传或下载文件,无论如何)。现在怎么办 ?Node.js 应用程序现在被阻止了吗?如果是 - 它如何不破坏应用程序的性能,如果不是 - 谁负责“跳跃” 在不同的事件和请求之间?我们知道,在 apache 或类似服务器中,有特殊的代码来处理所有线程(对它们进行计时),因此没有线程阻塞所有其他线程。然而,据我所知,在 Node 中,有一个事件循环。当文件 I\O 完成时,它的回调会神奇地返回准备好的文件。尽管如此,服务器仍然需要做 I\O,不能逃避!事件循环中的代码是否定时?例如在不同的事件(回调..whatever)之间跳转,以便没有请求阻塞另一个?如果有,以什么方式?事件循环中的代码是否定时?例如在不同的事件(回调..whatever)之间跳转,以便没有请求阻塞另一个?如果有,以什么方式?事件循环中的代码是否定时?例如在不同的事件(回调..whatever)之间跳转,以便没有请求阻塞另一个?如果有,以什么方式?
3 回答
所有的 I/O 都由 node.js 使用多个线程在内部处理;它是单线程、基于事件和异步的 I/O 功能的编程接口。
因此,您的示例的大上传由 node.js 管理的单独线程执行,当该线程完成其工作时,您的回调将被放入事件队列(由单个 JavaScript 线程执行)。
将单个 JavaScript 线程视为从队列头部拉出回调并串行执行它们,直到队列为空。然后它会休眠,直到其中一个内部 I/O 线程在队列中放置一个新的回调。
本文讨论了process.nextTick
帮助我理解其中一些细节的相关主题。
尽管 node.js 通常被描述为“非阻塞”,但真正的意思是它不会在 i/o 上阻塞。如果它必须做一些处理器密集型的事情,当然,其他事情必须等待。但如果它只是等待从文件系统或网络返回数据,node 不会阻塞你的进程。
在文件上传缓慢的情况下,它正在处理,定期它必须做一些事情,因为数据进来(可能调用你的回调,但可能只是存储该数据直到它有足够的调用你的回调)。但是计算机速度很快,无论发生什么,无论出于何种意图和目的,都是瞬时的。我们担心的是网络操作相对较慢的事实。在像 Php 这样的语言中,通常,在此操作完成之前,您的函数不会返回,并且在该脚本中您无能为力,直到发生这种情况。同时,CPU 可能处于空闲状态……只是等待数据通过网络进入。另一方面,在调用回调之前,Node 让您将 CPU 用于其他事情。
正如其他人所指出的那样,引擎盖下可能存在线程。或者可能没有,因为节点可以使用非阻塞 C++ 函数在内部实现文件和网络操作。没关系。重要的是 i/o 操作不会阻止您的应用程序中发生其他事情。
我认为这个主题足够复杂(至少对于新手来说)值得彻底阅读,并且无法通过阅读 5 行答案来理解。这是我找到的最佳资源http://www.theserverside.com/discussions/thread.tss?thread_id=61693 。他对 Node.js 的评价并不高,但他确实花了很多功夫来解释它。在我看来值得一读。