Node.JS分叉管道

Node.JS Forked Pipe

本文关键字:管道 分叉 JS Node      更新时间:2023-09-26

我试图fork一个node.js模块作为子进程每张贴在这个stackoverflow问题的例子。分叉本身可以工作,但我遇到的问题是节点试图在fork('./DaemonSerial.js'填充tChild之前添加.on('data').on('exit')

var fork = require('child_process').fork;
// Start Serial Daemon/s
var tChild = fork('./DaemonSerial.js', [], {
  stdio: 'pipe'
});
tChild.stdin.on('data', function(data) {
  // output from the child process
  console.log("./DaemonSerial.js >>> " + data)
 });
EdgeMaster.Children[tChild.pid] = tChild;
tChild.on('exit', function(d) {
    console.log("./DaemonSerial.js >>> "+ tChild.pid + ' Exited:'+ d);
    delete EdgeMaster.Children[tChild.pid]
 });

我在其他地方也遇到过这个问题,我有理由确信应该有一种方法来强制do THIS then THAT类型的功能,即使函数本身没有回调。child_process.fork(modulePath, [args], [options])在nodejs.org/api/child_process.html上没有列出回调。

想法?

编辑:我写了一个新的脚本forktest.js,以排除任何可能性,我的脚本的其他部分可能会导致问题。forktest.js完全如下:

var fork = require('child_process').fork;
var ForkDict = {};
function forkit(aPath){
    tChild = fork( aPath, [], {stdio: 'pipe'});
    ForkDict[tChild.pid] = tChild;
    ForkDict[tChild.pid].path = aPath;
    tChild.stdout.on('data', function(data) {
        // output from the child process
        console.log( this.path +'>>> '+ data);
     }.bind(this));
    tChild.on('exit', function(d) {
        console.log( this.path +'>>> Exited:'+ d);
        delete ForkDict[tChild.pid]
     }.bind(this));
}
forkit('./DaemonSerial.js');

控制台的错误如下所示:

pi@raspberrypi ~ $ node forktest.js
/home/pi/forktest.js:9
    tChild.stdout.on('data', function(data) {
                  ^
TypeError: Cannot call method 'on' of null
    at forkit (/home/pi/forktest.js:9:19)
    at Object.<anonymous> (/home/pi/forktest.js:19:1)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:901:3

fork是异步的,但是它的返回值不是异步填充的。它返回一个ChildProcess的实例,继承自EventEmitter。EventEmitter通常用于异步任务,但您在发生事件时接收事件,而不是使用回调。就像文档里说的:

这些方法遵循常见的异步编程模式(接受回调或返回EventEmitter)。

在第一个例子中:

  • fork没有stdio选项。您可能应该使用silent: true;它调用spawn, stdio选项设置为"pipe"。
  • 您尝试从可写流(stdin)中读取:tChild.stdin.on('data', ...,您可能想使用stdout

似乎stdinstdout可以是null,这取决于你是否使用silent: truefork:

参见文档中的options.silent

Boolean如果为真,则子进程的stdin, stdout和stderr将通过管道传递给父进程,否则它们将从父进程继承,详细信息请参见spawn()的stdio的"pipe"answers"inherit"选项(默认为false)

所以数据只是去你的主脚本的stdout。您可以使用(请注意,您的stdio选项没有做任何事情)来修复此问题:

tChild = fork( aPath, [], {silent: true});

如前所述,您需要在stdout上收听data事件。