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

2024-06-19

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

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 via:

node a.js

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

有什么提示吗?相同的代码在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,即使没有延迟,两条消息也会正确显示,因此很可能是管道通信出现问题,而不是管道通信出现问题process.exit.

更多更新 2014 年 7 月 3 日

评论中有人猜测process.exit()可以终止两个进程(都a.ja and b.ja)。不,它仅终止生成/分叉的进程,我通过添加无限来检查这一点setTimeout to a.js,之后就可以愉快地工作了b.ja已终止,但仍然没有“DEBUG 2”行。


为了清晰起见,主要编辑:

您面临的问题是之间的并发事件console.log('DEBUG2') and 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

但这很麻烦,而且你无法知道会有多少个“等待”。另一个解决方案是让 b.js 继承 stdout,这样就没有事件可以生成:

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 的另一个解决方案可以工作,但我不知道它是如何工作的。

EDIT:

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在Windows上正确使用node.js child_process.spawn()重定向? 的相关文章

随机推荐