在所有i:node.js之后循环遍历x

时间:2013-09-11 15:46:44

标签: javascript node.js

我有这个代码。我想遍历数据库中的所有用户,并为每个用户获取他们的投资组合列表(这反过来又是股票的集合):

 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的工作方式有关吗?

非常感谢任何帮助。谢谢。

3 个答案:

答案 0 :(得分:1)

getPortfolio()很可能是异步操作,并且根据内部实现,它可以将调用排队或将它们转换为http请求,例如,这可能需要一些时间,当这些请求完成时,只有你的回调函数用x操作将被调用。 但同时getPortfoli()调用将返回。这就是为什么你看到它在你所有的i上快速迭代,然后你才回调开始被调用。

答案 1 :(得分:1)

缺少JOIN对于那些带有node.js(事件驱动)和NoSQL数据库的SQL背景的用户来说真的很混乱。

为您的任务考虑流程

  1. 加载所有用户。
  2. 遍历每个用户并记录用于收集关系的字段(在您的情况下为用户名),通常是_id。 2B。 (可选)make object,其中key - 将是关系字段,在您的情况下为username,value - 将自己对象。
  3. 使用类似查询对相关集合进行另一次查询:{ _id: { $in: ids } }其中ids将是用户_id的数组。在您的情况下,您需要用户名列表。
  4. 遍历每个项目组合项并将其添加到用户对象。如果2b确实 - 则不需要两次迭代。
  5. 用户已完成,并拥有可供使用的投资组合数据。

答案 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');
  },