我想使用异步来使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跳到计算或更新而不等待查询完成。任何人都可以帮助我解决这个问题,谢谢。
答案 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
调用的情况。