Node.JS分叉pipe道
我试图将一个node.js模块作为一个subprocess发布在这个stackoverflow问题上发布的示例。 fork本身是可以工作的,但是我.on('data')
的问题是节点试图在fork('./DaemonSerial.js'
填充fork('./DaemonSerial.js'
之前添加.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
types的function的方法,即使这个函数本身没有callback。 child_process.fork(modulePath, [args], [options])
不会列出callback。
想法?
编辑:我写了一个新的脚本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
是asynchronous的,但是它的返回值不是asynchronous填充的。 它返回一个从EventEmitterinheritance的ChildProcess实例。 EventEmitter通常用于asynchronous任务,但是当发生某些事件而不是使用callback时会收到事件。 就像它在文档中所说:
这些方法遵循常见的asynchronous编程模式(接受callback或返回EventEmitter)。
在第一个例子中:
-
fork
没有stdio
选项。 你应该使用silent: true
来代替; 调用stdio
选项设置为“pipe道”。 - 您尝试从可写入的stream(stdin)读取:
tChild.stdin.on('data', ...
您可能想要使用stdout
。
看来stdin
和stdout
可以是null
这取决于你是否使用silent: true
或者not。 请参阅fork
的文档中的options.silent
:
Boolean
如果为true,则stdin,stdout和stderr将被传送到父级,否则将从父级inheritance,请参阅spawn()的stdio的“pipe”和“inherit”选项以获取更多详细信息默认为false
)
所以这些数据只是去你的主要脚本的stdout
。 你可以解决这个问题(注意你的stdio
选项没有做任何事情):
tChild = fork( aPath, [], {silent: true});
正如我前面所说,你需要听stdout
上的data
事件。