Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 子进程是立即执行的,还是在事件循环的未来迭代中执行的?_Node.js - Fatal编程技术网

Node.js 子进程是立即执行的,还是在事件循环的未来迭代中执行的?

Node.js 子进程是立即执行的,还是在事件循环的未来迭代中执行的?,node.js,Node.js,process_child.spawn()是立即启动进程,还是等待当前执行上下文清除堆栈 “spawn…遵循其他Node.js API典型的惯用异步编程模式。” 这是否意味着进程执行被延迟为回调队列事件,在spawn()调用方的执行上下文清除堆栈后由事件循环拾取 我担心的是,生成的进程可能会在我的代码有机会为它们安装处理程序之前触发事件(例如,写入stdout)。我似乎不是唯一一个有这种担心的人: 文档中说,“spawn…遵循其他Node.js API典型的惯用异步编程模式。” 这是否意味着进程

process_child.spawn()是立即启动进程,还是等待当前执行上下文清除堆栈

“spawn…遵循其他Node.js API典型的惯用异步编程模式。”

这是否意味着进程执行被延迟为回调队列事件,在spawn()调用方的执行上下文清除堆栈后由事件循环拾取

我担心的是,生成的进程可能会在我的代码有机会为它们安装处理程序之前触发事件(例如,写入stdout)。我似乎不是唯一一个有这种担心的人:

文档中说,“spawn…遵循其他Node.js API典型的惯用异步编程模式。”

这是否意味着进程执行被延迟为回调队列事件,在spawn()调用方的执行上下文清除堆栈后由事件循环拾取

不,这并不意味着。惯用的异步编程模式是在当前tick中启动异步操作,然后一旦启动并通过其他方式执行或控制,控制就会返回到Javascript。未来事件将在该点传达其状态或结果。其他典型的异步操作(如文件I/O或网络I/O)也是如此

与大多数异步API一样,它会同步调用操作系统,告诉它启动另一个应用程序,然后在它将控制权返回给JS之前,实际启动另一个进程的工作量取决于操作系统和特定操作系统上实现的内部结构。为了更确切地知道它在返回之前等待什么,您必须检查特定平台的本机代码源代码,然后必须深入研究它在您的平台上使用的操作系统调用

一般的模型是异步操作被启动,然后它将控制权返回给JS。由于此异步操作中正在进行的是启动一个新进程,并且操作系统负责另一个进程中的实际工作,因此node.js没有任何理由将实际调用操作系统的时间推迟到事件循环的未来时间。在事件循环的未来勾选之前,您无法从新流程中获取任何事件,因为这些事件都通过事件队列

通过node.js源代码,它可以在libuv中调用
uv\u spawn()
(跨平台库node.js是基于此构建的)。在我看来,到目前为止,一切都是同步的(无需等待下一个滴答声)。下一步是查看libuv代码,了解
uv\u spawn()
的作用

有趣的是,在跟踪源代码时,异常或同步错误会在内部捕获,并在将来的时间点上作为事件发出(不是同步的)。这允许您从
spawn()
调用获取从函数返回的子进程对象,在其上安装事件处理程序,并且不会错过任何事件

uv\u spawn()
源代码是,它似乎在同一个刻度上对
fork()
进行操作系统调用

太长,读不下去了 因此,我看不到有任何证据表明有任何人有意推迟实际的操作系统调用,以便在将来启动新进程。它似乎在同一时间调用操作系统。有证据表明,为了简化界面的使用,将错误报告推迟到未来某个时间


除了您添加的附加点之外,接收stdio和stdout的流是在新进程启动之前设置的。由于它们将通过JS事件队列从新进程接收数据,只要您在调用
spawn()
(例如,不是在某些异步回调中)的同一刻度中在这些流上设置自己的事件处理程序,那么这些事件处理程序将在stdio和stdout流上接收和通知任何数据之前安装。这是node.js Javascript的单线程、事件驱动特性的产物。

如果您告诉我们为什么您想知道这一点以及它如何影响您的编程或代码,我们可能会对您提供更全面的帮助。@jfriend00我添加了为什么我想知道以及它如何影响我的编程。感谢所有的反馈!正如我的回答所解释的,只要在调用
spawn()
(例如,不是在某个异步回调中)的同一个勾号中安装事件处理程序,就不存在缺少stdio事件的问题,所有的stdio数据都是通过事件队列来的,因此只有在事件循环的某个未来周期内才会到达,因此只要您在调用
spawn()
的同一周期内安装错误处理程序和任何侦听器,您就不会错过它们。