今天我的问题实际上是关于由于循环不能正常工作而发生的问题,但无论如何,如果我有关于设计的问题我会很开心。
app.post('/admin/earning/:multiplier', function (req, res) {
var multiplier = req.params.multiplier;
var now = new Date();
var List=[];
var dailySaving;
// Getting the investors emails(key) from the collection.
db.getInvestorsFromValidatedInvests(function(err,result){
if(err){console.log(err);}
console.log(result);
List = result;
console.log('Inside the List scope'+List[0]);
for(var i=0;i<List.length;i++){
db.returnTotalInvestingfromValidatedInvests(List[i],function(err,rst){
if(err){console.log(err);}
console.log(rst);
var dailySaving = ((rst*multiplier)/100);
console.log('Daily Savings which is going to be added is that : ' +dailySaving);
console.log(List[i]);
db.multiplyInvestAndAddSavings(List[i],dailySaving,function(err,rest){
if(err){console.log(err);}
console.log(rest);
});
});
}
});
res.json('Going to be Prepared...');
});
&#13;
在这里,我将分享您的每个数据库功能:
第一个函数从db获取所有者的电子邮件并返回一个数组,然后,我想对这个数组的每个元素进行一些操作,我决定使用for循环,但它无法正常工作。
Db.prototype.getInvestorsFromValidatedInvests = function(callback){
MongoClient.connect("mongodb://xxxxxxx:xxxxxxx@ds9999.mlab.com:99986/xxxxxx", function (err, db) {
if (err) { return console.dir(err); }
db.collection('validatedInvests').distinct("owner",function(err,result){
if(err){console.log(err); callback(err,null);}
callback(null,result);
});
db.close();
});
}
&#13;
Db.prototype.returnTotalInvestingfromValidatedInvests = function(owner,callback){
MongoClient.connect("mongodb://xxxxxxxx:xxxxxxx@ds09999.mlab.com:9996/aslanservices", function (err, db) {
if (err) { return console.dir(err); }
db.collection('validatedInvests').find({"owner":owner}).toArray(function(err,result){
var sum=0;
if(err){console.log(err); callback(err,null);}
for(var j=0;j<result.length;j++){
sum+=parseInt(result[j].amount);
}
callback(null,sum);
});
db.close();
});
}
&#13;
Db.prototype.multiplyInvestAndAddSavings = function(owner,amount,callback){
MongoClient.connect("mongodb://xxxxxx:xxxxxxx@ds99996.mlab.com:39996/aslanservices", function (err, db) {
if (err) { return console.dir(err); }
console.log('Db talking amount is'+amount);
db.collection('investClients').updateOne({"email":owner},
{
$inc : {
"savingsAccount" : +amount
},
},
{
upsert : true
}
,function(err,result){
if(err){callback(err,null);}
callback(null,result);
});
db.close();
});
}
&#13;
输出结果为:
列表范围内&gt;让我们说blablabla@gmail.com
220
将要添加的每日储蓄是:8.8
未定义
150
将要添加的每日储蓄是:6
未定义
Db谈话量是8.8
Db谈话量是6
预期的输出是:
220
将要添加的每日储蓄是:8.8
blablabla@gmail.com
Db谈话量是8.8
150
将要添加的每日储蓄是:6
secondblablabla@gmail.com
Db谈话量是6
答案 0 :(得分:2)
问题是您正在使用内部具有异步功能的for循环。让我试着解释一下:
for(var i=0;i<List.length;i++){
// first iteration, the variable i is
}
现在执行第一个异步函数:
db.returnTotalInvestingfromValidatedInvests(List[i],function(err,rst){
/*this is an async callback which will be executed in a
different context in a later time, when the response is received*/
}
所发生的是执行for循环的主要执行不等待来自上述函数的响应(因为异步),并向前递增递增执行下一次迭代的变量i
使用您的函数db.returnTotalInvestingfromValidatedInvests
并继续它。
无论你的所有或任何回复是否已经到来,很快整个for循环就会结束。
您获得undefined
的原因是因为在循环结束时变量i
的值为List.length
,这意味着它正在访问List[list.length]
。由于最大索引始终为length-1
,因此始终未定义。
摘要:您必须以List[i]
某种方式跟踪元素,以便在触发最终(嵌套)函数的异步回调时,您可以更新正确的元素。有些人通过创建哈希来做到这一点,有些人通过将其逻辑转换为循环方式来实现同步。
<强>建议:强>
尝试在每个函数回调中注销i
,以查看快速更改的变量。
希望解释有所帮助:)
根据要求,这是一种方法:
function onInvestsDone(err, obj){
if(err!=null){
// something went wrong
}
else{
// do anything here with your final response
}
}
for(var i=0;i<List.length;i++){
returnInvests(List, i, onInvestsDone);
}
function returnInvests(listArray, index, cb){
db.returnTotalInvestingfromValidatedInvests(listArray[index],function(err,rst){
if(err){
console.log(err);
cb(err); // call callback with error
}
console.log(rst);
var dailySaving = ((rst*multiplier)/100);
console.log('Daily Savings which is going to be added is that : ' +dailySaving);
console.log(listArray[index]);
db.multiplyInvestAndAddSavings(listArray[index],dailySaving,function(err,rest){
if(err){
console.log(err);
cb(err); // call callback with error
}
console.log(rest);
// successfully done everything
cb(null, rest);
});
});
}