我在使用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 });
});
在我看来,您可能会饿死事件循环(从不给它任何周期来处理传入事件),这可能破坏处理网络甚至出站网络的能力。我建议您仅在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
其他注释:
this.produce.bind(this)
而不是仅使用this.produce
来确保在调用该函数时设置了正确的this
值。eventEmitter.emit()
是同步的。它不允许事件队列处理事件,并且eventEmitter
事件不会通过事件队列。process.send()
回调被异步调用,并为事件循环提供了足够的机会来处理所有正在等待的事件。它还可以确保在开始下一个CPU密集型迭代之前,已完全发送进程间消息,这将暂时再次阻止事件队列处理。这样,您可以确保在再次阻止事件队列之前完成所有通信。setTimeout()
上使事情开始了下一个迭代,但是我认为在开始下一个迭代之前确保进程间消息传递已经完成更加可靠。EventEmitter
,则实际上并不需要它。您可以直接在对象上调用方法,而不必使用EventEmitter
事件。