gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-10-31 22:48:19 33 4
gpt4 key购买 nike

我有一个干净的 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:

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);

但问题只有在我管道输出到父进程时才会出现:如果我删除silent,即使没有延迟,两条消息也会正确显示,所以这很可能是什么管道通信错误,而不是 process.exit

更多更新 03.07.2014

在评论中推测 process.exit() 可能会终止两个进程(a.jab.ja)。不,它只终止生成/ fork 的进程,我通过将无限的 setTimeout 添加到 a.js 来检查它,它在 b.ja 之后愉快地工作已终止,但仍然没有“DEBUG 2”行。

最佳答案

为清楚起见进行的主要编辑:

你面临的问题是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

现在,如果你放慢进程。结束:

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

编辑:

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

关于node.js - 如何在 Windows 上正确使用 node.js child_process.spawn() 重定向?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24484466/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com