eventemitter.emit方法不在节点js中返回

时间:2019-11-24 18:07:06

标签: javascript node.js ipc eventemitter event-loop

使用eventemitter.emit方法时遇到问题。

基本上这就是我想要做的。我有一个运行时间很长的进程(受CPU限制),它会生成输出对象,由于这是受CPU限制的进程,因此我使用fork()将其作为单独的进程运行。

class Producer extends EventEmitter {
    constructor() {
       this.on('MyEvent', this.produce);
    }

    produce(input) {
        var output = longRunningProcess();

        this.emit('MyEvent, output);
        process.send(output);
    }
}

var producer = new Producer();
producer.emit('MyEvent', 0); // To kick off the execution

一旦生成每个输出,我想将其发送到父进程。并使用它发出事件以产生另一个对象,等等。

现在,问题在于process.send(output)似乎没有被执行。我可以看到输出一个接一个地打印在控制台中。但是父级似乎没有从子级进程收到任何东西。据我了解,nodejs事件循环在完成当前任务并且堆栈为空之前不应该接管新任务,但这不是这种情况。

那么你们能帮我吗?

修改:父流程代码

this.producer = ChildProcess.fork('.path/to/produer.js'silent: true });
this.producer.on('message', (data) => {
    this.miningProcess.send({ type: "StopMining", body: 0 });
});

1 个答案:

答案 0 :(得分:1)

在我看来,您可能正在饿死事件循环(从不给任何周期处理传入事件),这可能破坏处理网络甚至出站网络的能力。我建议您仅在process.send()完成后才开始下一次迭代。

class Producer extends EventEmitter {
    constructor() {
        this.on('MyEvent', this.produce.bind(this));
    }

    produce(input) {
        let output = longRunningProcess();

        process.send(output, () => {
            // When the send finishes, start the next iteration
            // This should allow the node.js event queue to process things
            this.emit('MyEvent, output);
        });
    }
}

var producer = new Producer();
producer.emit('MyEvent', 0); // To kick off the execution

注释的其他注释:

  1. 您需要在事件处理程序上使用this.produce.bind(this),而不仅仅是this.produce,以确保在调用该函数时设置了正确的this值。
  2. 请记住,eventEmitter.emit()是同步的。它不允许事件队列处理事件,并且eventEmitter个事件不能通过事件队列。
  3. 此代码假定process.send()回调被异步调用,并为事件循环提供了足够的机会来处理所有正在等待的事件。它还可以确保在启动下一个CPU密集型迭代之前,已完全发送进程间消息,这将暂时阻止事件队列处理。这样,您可以确保在再次阻止事件队列之前完成所有通信。
  4. 您可能已经在适当的位置setTimeout()处进行了工作,以开始下一次迭代,但是我认为在开始下一次迭代之前确保进程间消息传递已完成更为可靠。
  5. 仅供参考,如果您不使用EventEmitter导出的内容(此处显示的内容除外),则不需要使用它。您可以直接在对象上调用方法,而不必使用EventEmitter事件。