如何在Windows上正确使用node.js child_process.spawn()redirect?

我有一个干净的Windows 8.1盒子,安装了node.js(v0.10.29)。 我有两个文件中的以下testing代码:

a.js

var sub = require('child_process').spawn('node', ['b.js'], {silent: true}); sub.stdout.on("data", function (data) {console.log(data.toString());}); 

b.js

 console.log("DEBUG 1"); console.log("DEBUG 2"); process.exit(); 

如果我通过执行a.ja

 node a.js 

我将在控制台输出中看到“DEBUG 1” – 但不是“DEBUG 2”。 如果我删除process.exit() ,两行将被正确显示。 这种奇怪的行为发生在forkspawn

任何提示? 相同的代码在linux上没有问题。

更新02.07.2014

看起来这不是exit()和log()之间的竞争条件,因为将其更改为纯序列会产生相同的错误:

 function print(text, next) { console.log(text); next(); } print("DEBUG 1", function () { print("DEBUG 2", function () { process.exit(); }); }); 

更新03.07.2014

silent没有在spawn()文档中列出,但它的工作原理。 它在fork文档中列出,正如我之前提到的,这个问题与fork相同。

看来,如果我介绍了最后一个输出和process.exit()之间的延迟,所有工作正常:

 console.log("DEBUG 1"); console.log("DEBUG 2"); setTimeout(function () {process.exit();}, 10000); 

但是,只有当我将输出pipe道输出到父进程时,问题才会体现出来:如果我删除了silent ,那么即使没有延迟,这两个消息也能正确显示,所以很可能是pipe道通信有问题,而不是process.exit

更多更新03.07.2014

在评论中推测, process.exit()可能会终止这两个进程( a.jab.ja )。 不,它终止只产卵/分叉进程,我通过添加无限setTimeouta.js ,它愉快地工作后b.ja终止,仍然没有“debugging2”行。

主要编辑清晰度:

你面对的问题是console.log('DEBUG2')process.end()之间的并发事件,它们中的两个同时被调用(几乎),而process.end()具有更高的优先级,完成后,让sub停止听事件,所以停止DEBUG2打印:

在你的代码中:

 a.js |b.js start spawn |start listen |send('DEBUG1') get DEBUG1 |send('DEBUG2') start the event |send KILL print DEBUG1 | get DEBUG2 start the event get KILL kill b.js //DEBUG2 haven t been printed 

现在,如果你放慢process.end:

b.js:

 console.log('DEBUG1'); console.log('DEBUG2'); setTimeout(function () { process.end(); }, 1000); a.js |b.js start spawn |start listen |send('DEBUG1') get DEBUG1 |send('DEBUG2') start the event |wait print DEBUG1 |wait get DEBUG2 |send KILL start the event print DEBUG2 get KILL kill b.js 

但是这很麻烦,你不知道会有多less“等待”。 另一个解决scheme是让b.jsinheritancestdout,所以没有事件要做:

a.js:

 var sub = require('child_process').spawn('node', ['b.js'], {stdio:[process.stdin, process.stdout, process.stderr]}); a.js |b.js start spawn |start listen |print DEBUG1 |print DEBUG2 |send KILL get KILL | kill b.js 

现在,没有错误的代码,但是你不能得到在a.js中打印的内容。 我认为process.nextTick的另一个解决scheme可以工作,但我不知道如何工作。

编辑:

process.exit()杀死b.js,这是预期的行为。 a.js看到data事件结束,所以有一个空的事件循环,所以杀死自己:)