如果我使用process.send(),node.js等待回调/响应

时间:2013-09-26 07:42:07

标签: javascript node.js child-process

我有一个主进程,这个分叉是一个孩子。这个孩子做了一些计算。在孩子的代码的某些方面,我想向父母询问一些数据。此请求是高度动态的,此时我想等待此请求的回答/响应。但是我如何等待process.send()或者是否可以向.send()添加回调函数?

我试图将我的问题分解为一个简单的例子。 在我的例子中,高度动态的值是worker中的randomval。 我知道这个任务

var c = process.send({msg:'get_c',randomval:Math.floor((Math.random()*10)+1)});

无法正常工作。但我不知道如何描述问题。

main.js

var childProcessCalc = require('child_process').fork(__dirname + '/worker');
childProcessCalc.send({msgtype:'docalc'});

childProcessCalc.on('message',function(msg){
if(msg.msg === 'pi')
{
    console.log("Pi"+msg.pi+" by c="+msg.c);
}
else if(msg.msg === 'get_c')
{
    console.log('child wants c');
    childProcessCalc.send({msgtype:'your_c',c:1000000*msg.randomval});
}
});

childProcessCalc.on('exit',function(){
    console.log('main:the childProzess has exit!')
});  

worker.js

process.on('message', function(msg){

if(msg.msgtype == 'docalc') {
    //Here is my Problem, how to wait for the message thats the response for
    //exactly this send / randomval, or how to add a callback to send
    var c = process.send({msg:'get_c',randomval:Math.floor((Math.random()*10)+1)});

    var Pi=0;
    var n=1;
    for (var i=0;i<=c;i++)
    {
        Pi=Pi+(4/n)-(4/(n+2))
        n=n+4
    }
    process.send({msg:'pi',pi:Pi,c:c})
}
else if(msg.msgtype === 'your_c')
{
    console.log('parent hase sendc='+msg.c);
}

});

2 个答案:

答案 0 :(得分:1)

我有一个问题的解决方案,它适用于我,但因为我在nodejs非常新,我仍然不是现在,如果这是最好的方式。它感觉像一个开销。

用几句话说我做了什么: 我添加了一个对象,它存储一个带有回调函数的随机回调标识符,如果我们得到给定回调标识符的响应,则必须调用该回调函数。 当我现在从工作者调用send()时,我将标识符发送到主进程,主进程在完成后发回该标识符。所以我可以在我的回调var(dynamicMassages)中查找callbackfnc以调用并执行它。

main2.js

var childProcessCalc = require('child_process').fork(__dirname + '/worker2');
childProcessCalc.send({msgtype:'docalc'});

childProcessCalc.send({msgtype:'docalc'});

childProcessCalc.on('message',function(msg){
if(msg.msg === 'pi')
{
    console.log("Pi"+msg.pi+" by c="+msg.c);
}
else if(msg.msg === 'get_c')
{
    console.log('child wants c');
    childProcessCalc.send({msgtype:'your_c',callbackid:msg.callbackid, c:1000000*msg.randomval});
}
});

childProcessCalc.on('exit',function(){
    console.log('main:the childProzess has exit!')
});

worker2.js

var dynamicMassages = {};

process.on('message', function(msg){

var getRandomId = function(){
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for( var i=0; i < 5; i++ )
    {
        text += possible.charAt(Math.floor(Math.random() * possible.length));
    }

    if(dynamicMassages[text] === undefined)
    {
        return text;
    }
    else
    {
        return getRandomId();
    }
};

if(msg.msgtype == 'docalc') {
    var randomId = getRandomId();
    var callbackFnc = function(c){
        var Pi=0;
        var n=1;
        for (var i=0;i<=c;i++)
        {
            Pi=Pi+(4/n)-(4/(n+2))
            n=n+4
        }
        console.log("callbackFnc For:"+randomId);
        process.send({msg:'pi',pi:Pi,c:c})
        delete dynamicMassages[randomId];
    };

    dynamicMassages[randomId] = callbackFnc;//callbackFnc;
    process.send({msg:'get_c',callbackid: randomId, randomval:Math.floor((Math.random()*10)+1)});


}
else if(msg.msgtype === 'your_c')
{
    console.log('parent hase sendc='+msg.c+' for callbackId '+msg.callbackid);
    if(msg.callbackid !== undefined)
    {
        dynamicMassages[msg.callbackid](msg.c);
    }
}

});

如果您愿意,请发表评论。

答案 1 :(得分:0)

我建议您使用消息总线,或者使用RabbitMQ这样的全面高级解决方案,或者使用axon这样的小解决方案。

基本上,你想要做的是进程间通信,我会尽可能地坚持已建立的协议和标准,并避免滚动你自己的解决方案。由于RabbitMQ建立在AMQP之上,我想你可以称之为标准