首页 > 解决方案 > 与子进程同步运行 JavaScript 的最佳方法是什么?

问题描述

问题:(编辑2处的解决方案)

我正在使用 NodeJS 运行 JavaScript。

我有一个读取和写入管道的子进程。这是在由其他代码调用的类中。写入子进程管道后,我需要等待答案,然后返回答案。实现这一目标的最佳方法是什么?

据我了解,您打算在 JavaScript 中使用事件,someStream.on('data', (data) => {...});但这需要在检查事件循环之前由 Node 处理整个 JavaScript 文件。但在这种情况下,我需要在完成脚本执行之前输出流。我知道这不是使用 JavaScript 的预期方式,但我正在修改现有包并且无法在界面中进行更改。

我知道 spawnSync/execSync 但这不是一个好的解决方案,因为生成的进程的输出需要多达 10 000 次,并且生成的程序在 JVM 上运行。

这是我正在尝试做的一个简化示例:

const {spawn} = require("child_process");

class Context {
    constructor() {
        this.program = spawn("/path/to/some/program", ["my", "arguments"]);
    }

    someMethod(string) {
        if (this.program.stdin.write(string + "\n") == null) {
            console.log("Program stdin overflow");
        }

        var result = /* Here I need the output of the program. */;
        if (result == "some output") {
            return true;
        } else {
            return false;
        }
    }

}

编辑 1

NodeJS 版本是旧的 8.12,但无法更改。

编辑 2

解决了。我在一个小的辅助 C 程序上作弊,child_process.spawnSync()它的唯一目的是通过使用命名管道传递来自子进程的信息。这种方式从同步代码期间获得的活动子进程的信息。也可能fs.readSync()在命名管道上使用忙等待,但需要阻塞调用。

标签: javascriptnode.jssynchronizationpipechild-process

解决方案


JavaScript/node 是一种事件驱动语言,您会很高兴知道您可以设置基于事件的接收流数据。这就是你处理这个问题的方式,这是 JavaScript 做得很好的事情。

正如您在回复评论中提到的那样, ChildProces 类具有 子进程的标准、、和流的stdin成员stdoutstderr流有几个事件,其中之一是data.

在实践中,它看起来像这样:

const { spawn } = require("child_process");

const bash = spawn("/bin/sh", ["-c", `
  while true; do echo 'doing stuff'; sleep 1s; done
`]);

bash.stdout.on('data', d => {
  console.log(d.toString('utf8'));
});

bash.stderr.on('data', e => {
  console.log('err', e);
});

这就是您从子进程接收通信的方式。当然,可以使用stdin管道将信息发送回子进程,只有你会做一个writepipe或一些事情。这些不需要是事件,因为 JavaScript 控制它们何时发生。因此,您只需在需要时写入数据。


推荐阅读