我试图根据此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
; 这就要求spawn
与stdio
设置为"管道"选项.
您尝试从可写流(stdin)读取:tChild.stdin.on('data', ...
您可能想要使用stdout
.
看来,stdin
和stdout
可null
取决于如果你使用silent: true
与否.请参阅options.silent
文档fork
:
Boolean
如果为true,则将子节点的stdin,stdout和stderr传送给父节点,否则它们将从父节点继承,请参阅spawn()的stdio的"pipe"和"inherit"选项以获取更多详细信息(默认值)是false
)
所以数据只是你的主脚本stdout
.您可以解决此问题(请注意您的stdio
选项没有做任何事情):
tChild = fork( aPath, [], {silent: true});
正如我之前所说,你需要听一下这个data
事件stdout
.
fork
是异步的,但它的返回值不是异步填充的.它返回一个继承自EventEmitter的ChildProcess实例.EventEmitter通常用于异步任务,但是在发生某些事件而不是使用回调时会收到事件.就像在文档中说的那样:
这些方法遵循常见的异步编程模式(接受回调或返回EventEmitter).
在第一个例子中:
fork
没有stdio
选择.你可能应该使用silent: true
; 这就要求spawn
与stdio
设置为"管道"选项.
您尝试从可写流(stdin)读取:tChild.stdin.on('data', ...
您可能想要使用stdout
.
看来,stdin
和stdout
可null
取决于如果你使用silent: true
与否.请参阅options.silent
文档fork
:
Boolean
如果为true,则将子节点的stdin,stdout和stderr传送给父节点,否则它们将从父节点继承,请参阅spawn()的stdio的"pipe"和"inherit"选项以获取更多详细信息(默认值)是false
)
所以数据只是你的主脚本stdout
.您可以解决此问题(请注意您的stdio
选项没有做任何事情):
tChild = fork( aPath, [], {silent: true});
正如我之前所说,你需要听一下这个data
事件stdout
.