我刚刚尝试使用子进程并注意到exit事件在close事件之前触发 - 以下代码抛出错误,因为this._instance.stdin不再存在(this._instance已经为null)。
'use strict';
const spawn = require('child_process').spawn;
class Foo {
constructor() {
this._instance = null;
}
bar() {
this._instance = spawn('ls', ['-l']);
this._instance.on('close', (code, signal) => {
this._instance.stdin.end();
});
this._instance.on('exit', (code, signal) => {
this._instance = null;
});
return this._instance;
}
}
var foo = new Foo();
console.log(foo.bar());
文档说明:
“请注意,当'exit'事件被触发时,子进程stdio流可能仍然是打开的。”
我想知道这是怎么发生的,为什么在流程退出后流仍然存在?它们是如何“关闭”的,这个部分是由操作系统处理还是节点在stdio流上关闭左边?
在实践中,我不一定在退出时将this._instance设置为null,因为它看起来不是一件好事,显然有点过早。
答案 0 :(得分:1)
close
event的文档阐明了为什么会发生这种情况。
简而言之,stdio可以被其他尚未退出的进程使用。
我还没有查看代码本身,但操作系统处理关闭stdio流的部分是有意义的。考虑将stdio管道化为多个进程(使用tee
的管道可能是一个很好的例子。)
在提交的案例中,我怀疑你甚至不需要end()
stdin,因为close
事件表明stdin流已经关闭。