3

我正在尝试child_process.spawn()在 Meteor 方法中使用。我想从外部进程捕获 PID、stdout、stderr 和退出代码,并将所有这些存储在数据库中。

一切正常,直到我添加了第一个insert()电话。这样insert(),只有一个“虚拟”文档被插入到数据库中。我在服务器控制台中没有收到错误消息。如果我先注释掉insert(),其他insert()调用会成功。

// server/app.js
var spawn = Npm.require('child_process').spawn;

Meteor.methods({
  start: function() {
    var child = spawn('ls', ['/tmp']);
    var pid = child.pid;

    var wrappedChildStdoutOn = Meteor.wrapAsync(child.stdout.on, child.stdout);
    var wrappedChildStderrOn = Meteor.wrapAsync(child.stderr.on, child.stderr);
    var wrappedChildOn = Meteor.wrapAsync(child.on, child);

    // this insert() breaks upcoming insert() calls!
    Stuff.insert({pid: pid, date: new Date(), type: 'dummy', data: 'dummy'});

    wrappedChildStdoutOn('data',  function (data) {
      Stuff.insert({pid: pid, date: new Date(), type: 'stdout', data: data.toString()});
    });

    wrappedChildStderrOn('data', function (data) {
      Stuff.insert({pid: pid, date: new Date(), type: 'stderr', data: data.toString()});
    });

    wrappedChildOn('exit', function (code) {
      Stuff.insert({pid: pid, date: new Date(), type: 'exit', code: code});
    });
  }
});

第一次insert()打电话是怎么回事?

这是一个演示该问题的 Meteor 应用程序

4

1 回答 1

1

insert需要一些时间,所以在ls完成之前完成它的输出insert。当您将事件处理程序放置到位时,为时已晚。

您可以通过将第一个insert移到末尾、insert在调用之前移动第一个spawn或添加无操作function () {}回调来解决此问题,insert以便异步调用它。

于 2015-05-08T12:25:01.060 回答