javascript - 与子进程同步运行 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()
在命名管道上使用忙等待,但需要阻塞调用。
解决方案
JavaScript/node 是一种事件驱动语言,您会很高兴知道您可以设置基于事件的接收流数据。这就是你处理这个问题的方式,这是 JavaScript 做得很好的事情。
正如您在回复评论中提到的那样, ChildProces 类具有 子进程的标准、、和流的stdin
成员stdout
。stderr
流有几个事件,其中之一是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
管道将信息发送回子进程,只有你会做一个write
或pipe
或一些事情。这些不需要是事件,因为 JavaScript 控制它们何时发生。因此,您只需在需要时写入数据。
推荐阅读
- javascript - 如何在网页中预览上传的视频
- php - chmod -R 775 适用于 Windows 10
- node.js - 如何使用 Firebase 函数在 Firebase 实时数据库的数据数组中添加新字段?
- javascript - 为什么我在 vue js 中收到“无法读取未定义的属性‘状态’”的错误
- c++ - 如何按值的升序对 std::map 进行排序?
- sip - E2U+sip 与 sip+E2U
- javascript - 如何将 XML 数据包装在 HTML 表中?
- python - 如何在 python lxml 包中的 XPATH 表达式中设置数组索引
- compiler-construction - 点文件不为 -view-isel-dags 选项生成
- android - 关于移动应用程序(Android/iOS)的数据库解决方案的建议