Node.js中包含子进程的自定义事件

时间:2013-05-12 11:48:02

标签: node.js

我目前正在使用子进程,以便以非阻塞方式运行某些计算功能。

我遇到了一个问题,我需要能够将计算结果与父进程中的正确回调联系起来。例如:

var cp = require('child_process');
var n = cp.fork(__dirname + '/child.js');

exports.evaluate = function(data, callback) {

    n.send({ data : data});

    n.once('message', function(result) {

        callback(result);

    }

}

这个例子的问题是,如果一个计算在另一个计算之前返回,那么它将不会收到正确的结果。

有没有办法使用自定义事件名称而不是'message'来确保每次调用evaluate函数时都会创建一个唯一的侦听器,一旦调用它就会被删除?

如何使用子进程发出自定义事件?

提前致谢!

3 个答案:

答案 0 :(得分:5)

使用new events.EventEmitter创建一个新的EventEmitter。然后根据您收到eventType:"someType"的任何邮件发出事件。

即。

之类的东西
 events = require("events")     
 emitter = new events.EventEmitter
 n.on("message", function(msg) { emitter.emit(msg.eventType,msg.body) })

然后将侦听器(使用onceon)绑定到该事件发射器。

答案 1 :(得分:0)

我认为一种不错的方法可能是递归调用您的evaluate函数,直到所有计算完成。使用队列进行计算并以FIFO方式处理它们。

var computations = [];

你需要抛弃n.once('消息'并且在你的evalutate函数之外定义一个n.on('消息'处理程序。使用每个'消息&# 39;您收到的符合您的评估数据类型(让我们称之为'结果')然后您将该结果保存在结果的FIFO队列中。之后,您将' ; d检查是否有更多的计算,并再次调用evaluate。如果你愿意的话,可以清理它,以便在evaluate函数中拼掉最旧的计算。

var results = [];

n.on('message', function(m) {
  if(m.msg === "result") { // message looks like {msg: "result", data: 1234}
    results.push(m.data);
  }
  if(computations.length > 0) {
    var comp = computations[0]; // Save oldest computation
    computations.splice(0,1); // Remove oldest computation from array
    evaluate(comp); // Evaluate oldest computation
  }
  else
    process_results(); // if you have 0 computations left, 
                       // you got the last result so go process them.
});

在调用evaluate之前,您应该将计算推送到队列中,并发送最旧的计算以进行评估。

if(computations.length > 0) {
  computations.push(new_comp); // Push on your newest compuation
  var comp = computations[0]; // Save oldest computation
  computations.splice(0,1); // Remove oldest computation from array
  evaluate(comp); // Evaluate oldest computation
}
else {
  evaluate(new_comp); // Evaluate computation
}
evaluate(new_comp); // Evaluate oldest computation

你的"完成"在calculate.length === 0时,标志将会出现。而这只会自然地用上面的代码来处理。任何时候你在n.on中留下0个计算('消息',处理程序..你可以调用你的结果处理函数:

要处理结果,这是一个简单的for循环。

function process_results() {
    if(results.length > 0)
      for(x in results)
        console.log("New result: "+x);
}

答案 2 :(得分:0)

这可能不是严格的“正确”,并且已经晚了6年以上,但似乎可以在2020年实现

> process.version
'v12.14.1'
> var ignore = process.on('custom',function(e){console.dir(e,{depth:null});})
undefined
> process.emit('custom',{e:"hello"})
{ e: 'hello' }
true
> 

即,传递给process.emit(x,obj)的任何对象都将发送到针对匹配的process.on(x,function(obj){ /* ... */ })回调进行注册的对象

希望这会有所帮助。