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

cin*_*vro 0 asynchronous node.js

我想使用async使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);
}
]);
Run Code Online (Sandbox Code Playgroud)

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

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);
}
]);
Run Code Online (Sandbox Code Playgroud)

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

Wir*_*rie 5

您正在声明ra函数块内部的变量,因此它们将作用于该函数并且在其他地方不可用.你需要把它们放在更方便的地方.例如,您可以将它们放在一个全局变量中:

var ra;

async.series([ ... ]);
Run Code Online (Sandbox Code Playgroud)

此外,当您使用系列时,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
        });
    });
Run Code Online (Sandbox Code Playgroud)

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