我试图根据this stackoverflow question上发布的示例将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
类型功能的方法,即使函数本身没有回调也是如此。 <{3}}上的child_process.fork(modulePath, [args], [options])
未列出回调。
想法?
编辑:
我写了一个新脚本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
答案 0 :(得分:9)
fork
是异步的,但其返回值不会异步填充。它返回一个继承自EventEmitter的ChildProcess实例。 EventEmitter通常用于异步任务,但是在发生某些事件而不是使用回调时会收到事件。就像它在docs中所说的那样:
这些方法遵循常见的异步编程模式(接受回调或返回EventEmitter)。
在第一个例子中:
fork
没有stdio
选项。您应该使用silent: true
代替;调用spawn
并将stdio
选项设置为“pipe”。tChild.stdin.on('data', ...
您可能想要使用stdout
。 stdin
和stdout
似乎可以是null
,具体取决于您是否使用silent: true
。请参阅options.silent
的文档中的fork
:
Boolean
如果为true,则将子节点的stdin,stdout和stderr传送给父节点,否则它们将从父节点继承,请参阅spawn()的“pipe”和“inherit”选项有关详细信息的stdio(默认为false
)
因此,数据只会转到主脚本的stdout
。你可以解决这个问题(注意你的stdio
选项没有做任何事情):
tChild = fork( aPath, [], {silent: true});
正如我之前所说,您需要在data
上收听stdout
事件。