Node.JS叉管

 书友53034809 发布于 2023-01-19 11:26

我试图根据此stackoverflow问题上发布的示例将node.js模块分叉为子进程.fork本身可以工作,但我遇到的问题是该节点正在尝试添加.on('data')和填充.on('exit')之前fork('./DaemonSerial.js'tChild

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. (/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

Aaron Dufour.. 9

fork是异步的,但它的返回值不是异步填充的.它返回一个继承自EventEmitter的ChildProcess实例.EventEmitter通常用于异步任务,但是在发生某些事件而不是使用回调时会收到事件.就像在文档中说的那样:

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

在第一个例子中:

fork没有stdio选择.你可能应该使用silent: true; 这就要求spawnstdio设置为"管道"选项.

您尝试从可写流(stdin)读取:tChild.stdin.on('data', ...您可能想要使用stdout.

看来,stdinstdoutnull取决于如果你使用silent: true与否.请参阅options.silent文档fork:

Boolean如果为true,则将子节点的stdin,stdout和stderr传送给父节点,否则它们将从父节点继承,请参阅spawn()的stdio的"pipe"和"inherit"选项以获取更多详细信息(默认值)是false)

所以数据只是你的主脚本stdout.您可以解决此问题(请注意您的stdio选项没有做任何事情):

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

正如我之前所说,你需要听一下这个data事件stdout.

1 个回答
  • fork是异步的,但它的返回值不是异步填充的.它返回一个继承自EventEmitter的ChildProcess实例.EventEmitter通常用于异步任务,但是在发生某些事件而不是使用回调时会收到事件.就像在文档中说的那样:

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

    在第一个例子中:

    fork没有stdio选择.你可能应该使用silent: true; 这就要求spawnstdio设置为"管道"选项.

    您尝试从可写流(stdin)读取:tChild.stdin.on('data', ...您可能想要使用stdout.

    看来,stdinstdoutnull取决于如果你使用silent: true与否.请参阅options.silent文档fork:

    Boolean如果为true,则将子节点的stdin,stdout和stderr传送给父节点,否则它们将从父节点继承,请参阅spawn()的stdio的"pipe"和"inherit"选项以获取更多详细信息(默认值)是false)

    所以数据只是你的主脚本stdout.您可以解决此问题(请注意您的stdio选项没有做任何事情):

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

    正如我之前所说,你需要听一下这个data事件stdout.

    2023-01-19 11:28 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有