简体   繁体   English

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

[英]eventemitter.emit method doesn't return in node js

I have a problem using eventemitter.emit method.我在使用 eventemitter.emit 方法时遇到问题。

Basically this is what I want to do.基本上这就是我想要做的。 I have a long running process (CPU bounded) that generates output objects, and since this is CPU bounded process i run it as a separate process using fork().我有一个长时间运行的进程(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

And once each output is generated, I want to send it to the parent process.一旦生成每个输出,我想将其发送到父进程。 And also use it to emit an event to produce another object and so on.并且还使用它来发出一个事件来产生另一个对象等等。

Now, the problem is that the process.send(output) doesn't seem to be executed.现在,问题是process.send(output)似乎没有被执行。 I can see the outputs being printed in the console one after one.我可以看到输出一个接一个地打印在控制台中。 But the parent doesn't seem to be receiving anything from the child process.但是父进程似乎没有从子进程收到任何东西。 In my understanding, nodejs event loop shouldn't pick up a new task until it finishes the current one and the stack is empty, but this is not the case here.在我的理解中,nodejs 事件循环在完成当前任务并且堆栈为空之前不应该选择新任务,但这里的情况并非如此。

So can you guys help me with this?所以你们能帮我解决这个问题吗?

Edit : Parent process code编辑:父进程代码

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

It looks to me like you may be starving the event loop (never giving it any cycles to processing incoming events) which can wreck the ability to process networking, even outbound networking.在我看来,您可能正在耗尽事件循环(从不给它任何处理传入事件的周期),这可能会破坏处理网络,甚至出站网络的能力。 I'd suggest that you start the next iteration only after the process.send() has completed.我建议您仅在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

Other comments of note:其他注意事项:

  1. You need this.produce.bind(this) on your event handler instead of just this.produce to make sure the right this value is set when that function is called.您需要在事件处理程序上使用this.produce.bind(this)而不仅仅是this.produce以确保在调用该函数时设置正确的this值。
  2. Keep in mind that eventEmitter.emit() is synchronous.请记住eventEmitter.emit()是同步的。 It does not allow the event queue to process events and eventEmitter events do not go through the event queue.它不允许事件队列处理事件并且eventEmitter事件不经过事件队列。
  3. This code assumes that the process.send() callback is called asynchronously and gives the event loop enough chances to process any events that are waiting.此代码假定process.send()回调是异步调用的,并为事件循环提供足够的机会来处理任何正在等待的事件。 It also makes sure the interprocess message is completely sent before you start the next CPU intensive iteration which will temporarily block the event queue processing again.它还确保在您开始下一个 CPU 密集型迭代之前完全发送进程间消息,这将再次暂时阻止事件队列处理。 This way, you are sure the whole communication is done before blocking the event queue again.这样,您可以确保在再次阻塞事件队列之前完成了整个通信。
  4. You probably could have made things work with an appropriately places setTimeout() to kick off the next iteration, but I think it's more reliable to make sure the interprocess messaging is done before kicking off the next iteration.您可能可以使用适当的地方setTimeout()来启动下一次迭代,但我认为确保在启动下一次迭代之前完成进程间消息传递更可靠。
  5. FYI, if you're not using the EventEmitter you derive from for anything other than is shown here, then it isn't really needed.仅供参考,如果您不使用从中派生的EventEmitter用于此处显示的以外的任何内容,那么它并不是真正需要的。 You could just call methods on your object directly rather than using EventEmitter events.您可以直接调用对象上的方法,而不是使用EventEmitter事件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM