使用node.js异步系列,但不起作用

时间:2013-08-27 23:15:58

标签: node.js asynchronous

我想使用异步来使node.js按顺序工作,首先从mongodb查询两个速率,然后使用这些速率计算两个新速率:

async.series([
    function(callback){
        db.collection('heros',function(err,collection){
            if(err){
                console.log(err);
            }
            if(!err){
                console.log("2 collection fetched!");
                collection.findOne({'id':win},function(err,result){
                    if (err) throw err;
                    rate1=result.rate;
                    console.log("win-rate:"+rate1);
                });
                collection.findOne({'id':lose},function(err,result){
                    if (err) throw err;
                    rate2=result.rate;
                    console.log("lose-rate:"+rate2);
                });         
            }
        });
        callback(null);

    }, function(callback){   
        var Ea= 1/(1+Math.pow(10,(rate2-rate1)/400));
        var Eb= 1/(1+Math.pow(10,(rate1-rate2)/400));
        var ra= rate1+16*(1-Ea);
        var rb= rate2+16*(0-Eb);
        console.log("ra:"+ra);
        console.log("rb:"+rb);
        callback(null);
    },
        function(callback){   
    db.collection('heros',function(err,collection){
        if(!err){
        collection.update({'id':win},{$set:    {rate:ra}},function(err,result){
          if(err) throw err;
          if(!err){
            console.log("update successful");
          }
          });
          collection.update({'id':lose},{$set:{rate:rb}},function(err,result){
          if(err) throw err;
          if(!err){
            console.log("update successful");
        }
        });

            }

    });
    callback(null);
}
]);

但是当我运行它时,会显示错误消息:

ReferenceError: ra is not defined

似乎nodejs跳到计算或更新而不等待查询完成。任何人都可以帮助我解决这个问题,谢谢。

1 个答案:

答案 0 :(得分:5)

您在功能块中声明了ra之类的变量,因此它们的范围限定为该函数并且在其他地方不可用。你需要把它们放在更方便的地方。例如,您可以将它们放在全局变量中:

var ra;

async.series([ ... ]);

此外,当您使用系列时,只有在该步骤的所有工作都已完成时才应调用callback功能。

例如,一个任务应如下所示:

db.collection('heros',function(err,collection){
        if(err){
            console.log(err);  // log the error
            callback(err);     // call the async call back with the error
            return;            // stop 
        }
        console.log("2 collection fetched!");
        collection.findOne({'id':win},function(err,result){
            if (err) { callback(err); return; } // again, handle error
            rate1 = result.rate;                // grab results
            console.log("win-rate:"+rate1);     // log
            callback(null, rate1);              // now indicate complete by calling
        });
    });

由于您在单个任务中有多个异步函数调用,您可能希望将它们拆分为多个任务或考虑使用parallel函数。您甚至可以在parallel调用中的其他任务中使用series来处理需要进行两次findOne调用的情况。