我有这个代码。我想遍历数据库中的所有用户,并为每个用户获取他们的投资组合列表(这反过来又是股票的集合):
calculatePortfolios: function(callback) {
var thisuser;
module.exports.getAllUsers(function(err, users) {
/* Loop through all users with i */
for(var i = 0; i < users.length; i++) {
console.log('i = ' + i);
console.log(users.length);
thisuser = users[i]; // Store current user.
/* Loop through all held stocks in current user's portfolio. */
module.exports.getPortfolio(thisuser.username, function(err, portfolio) {
for(var x = 0; x < portfolio.length; x++) {
console.log('x = ' + x);
var total = parseFloat((portfolio[x].held * portfolio[x].unitprice) + thisuser.cash);
console.log(total);
console.log(thisuser.username);
module.exports.updateInvestor(thisuser.username, total, function(err, result) {
console.log(thisuser.username + ' ' + total);
});
}
});
}
callback(err, 'OK');
});
},
我得到的结果是所有i索引(用户)在所有x索引(组合)之前循环。 x不应该是i的内环吗?
这与Node.JS的工作方式有关吗?
非常感谢任何帮助。谢谢。
答案 0 :(得分:1)
getPortfolio()很可能是异步操作,并且根据内部实现,它可以将调用排队或将它们转换为http请求,例如,这可能需要一些时间,当这些请求完成时,只有你的回调函数用x操作将被调用。 但同时getPortfoli()调用将返回。这就是为什么你看到它在你所有的i上快速迭代,然后你才回调开始被调用。
答案 1 :(得分:1)
缺少JOIN
对于那些带有node.js(事件驱动)和NoSQL数据库的SQL背景的用户来说真的很混乱。
为您的任务考虑流程:
username
,value - 将自己对象。{ _id: { $in: ids } }
其中ids
将是用户_id的数组。在您的情况下,您需要用户名列表。答案 2 :(得分:1)
@PSL:让它与async.waterfall
合作。可能不是最优雅的解决方案,但它现在可以使用。
/**
* @description Calculate the value of an investor's portfolio.
* @function
*/
calculatePortfolios: function(callback) {
async.waterfall([
function(callback) {
var allUsers = [];
module.exports.getAllUsers(function(err, users) {
for(var i = 0; i < users.length; i++) {
allUsers.push(users[i]);
}
});
callback(null, allUsers);
},
function(allUsers, callback) {
var totals = [];
for(var i = 0; i < allUsers.length; i++) {
module.exports.getPortfolio(allUsers[i].username, function(err, portfolio) {
for(var x = 0; x < portfolio.length; x++) {
totals.push(parseFloat(portfolio[x].held * portfolio[x].unitprice));
}
});
}
callback(null, allUsers, totals);
},
function(allUsers, totals, callback) {
for(var i = 0; i < allUsers.length; i++) {
module.exports.updateInvestor
(allUsers[i].username, (totals[i] + allUsers[i].cash), function(err, result) {
console.log('Updated an investor!');
});
}
callback(null, 'OK');
}
]);
callback(null, 'OK');
},