[英]Looping through x after all i : node.js
I have this code. 我有这个代码。 I want to loop through all Users in a database and for each user get a list of their Portfolios (which in turn is a collection of stocks): 我想遍历数据库中的所有用户,并为每个用户获取他们的投资组合列表(这又是股票的集合):
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');
});
},
The result I get is that all i indices (users) are looped through before all x indices (portfolios). 我得到的结果是所有i索引(用户)都在所有x索引(投资组合)之前循环通过。 Shouldn't x be an inner loop of i? x难道不是i的内在循环吗?
Is this something related to how Node.JS works? 这与Node.JS的工作方式有关吗?
Any help is much appreciated. 任何帮助深表感谢。 Thank you. 谢谢。
the getPortfolio() is most likely an asynchronous operation, and depending on the internal implementation it may either queue the calls or translate them to http requests for example that may take time, when these requests are completed only then your callback function that operates with x will be called. getPortfolio()很可能是异步操作,并且取决于内部实现,它可能将调用排队或将它们转换为http请求,例如,这可能需要一些时间,当这些请求完成时,才可以使用x进行操作的回调函数将被称为。 But meanwhile getPortfoli() call will return. 但是与此同时,getPortfoli()调用将返回。 That is exactly why you see it iterating fast over all your i's, and only then you callback starts getting called. 这就是为什么您会看到遍历所有i的迭代很快,然后才开始调用回调的原因。
Lack of JOIN
's is really confusing to users who come with SQL background to node.js (event-driven) and NoSQL databases. 缺少JOIN
的用户的确使那些对Node.js(事件驱动)和NoSQL数据库具有SQL背景的用户感到困惑。
Consider this flow for your task: 为您的任务考虑以下流程 :
username
, and value - will be object it self. (可选)创建对象,其中键-将是关系的字段,在您的情况下为username
,值-将是其自身的对象。 { _id: { $in: ids } }
where ids
will be array of user _id's. 使用类似的查询对相关集合进行另一个查询: { _id: { $in: ids } }
其中ids
是用户_id的数组。 In your case you need list of usernames. 在您的情况下,您需要用户名列表。 @PSL: Got it working with async.waterfall
. @PSL:使用async.waterfall
。 Probably not the most elegant solution, but it works for now. 可能不是最优雅的解决方案,但它现在可以使用。
/**
* @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');
},
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.