为什么我的Node子进程是通过spawn()挂起创建的?

Tom*_*Tom 7 spawn node.js

我正在使用spawn()进行git调用.有时它工作正常,但其他似乎是悬挂.我看到没有事件触发(错误,退出,关闭),但我看到证据表明该过程实际上已成功完成.

var spawn = require('child_process').spawn;

spawn('git', ['push', 'origin', 'master'])
  .on('error', function(error) {
    console.log("ERROR: DETAILS: " + error);
  })
  .on('close', function(code) {
    console.log("SUCCESS: CODE: " + code);
  })
  .on('exit', function(code) {
    console.log("EXIT: CODE: " + code);
  })
Run Code Online (Sandbox Code Playgroud)

Tom*_*Tom 12

事实证明,一旦stderr缓冲区超过24kb,您必须从中读取它,否则您看不到任何完成事件.可能的解决方法:

  1. 在spawn调用上设置stdio选项.

    spawn('git', ['push', 'origin', 'master'], {stdio: 'ignore'});
    
    Run Code Online (Sandbox Code Playgroud)

    有关所有可能性,请参阅Node ChildProcess doc - 有很多.

  2. 添加一个on(数据)处理程序.

    var git = spawn('git', ['push', 'origin', 'master']);
    ...
    git.stderr.on('data', function(data) {
      // do something with it
    });
    
    Run Code Online (Sandbox Code Playgroud)
  3. 将它传递给stdout/stderr.这可能对您的应用程序来说过于冗长,但包括它的完整性.

    var git = spawn('git', ['push', 'origin', 'master']);
    ...
    git.stderr.pipe(process.stderr);
    git.stdout.pipe(process.stdout);
    
    Run Code Online (Sandbox Code Playgroud)

  • 在这种情况下,孩子没有挂,它已经退出了。但是,节点代码不会接收任何事件。我在子进程消失的地方看到了同样的事情,但节点从不触发退出或关闭事件,我的节点代码死锁等待发生的事情没有发生。对我来说,错误是间歇性的,不能 100% 可靠地重现。 (2认同)