簡體   English   中英

nodejs和mongodb(mongojs):嘗試在for循環中查詢和更新數據庫

[英]nodejs and mongodb (mongojs): Trying to query and update database within a for loop

我正在編寫一個多人游戲(mongojs,nodejs),並試圖找出如何根據游戲結果更新用戶統計數據。 我已經編寫了代碼來計算所有后期游戲統計數據。 當我嘗試在for循環中更新用戶的統計信息時出現問題。 這是我得到的:

//Game Stats
var tempgame = {
    gameid: 1234,
    stats: [
        {
            score: 25,
            user: 'user1'
        },
        {
            score: 25,
            user: 'user2'
        }
    ]
}


for(i = 0; i < tempgame.stats.length; i++){
    db.users.find({ username: tempgame.stats[i].user }, function(err, res){
        if( err != null){
            //handle errors here.
        } else {
            var userstats = res[0].stats;
            if( tempgame.stats[i].score > userstats.bestscore ){ //this is where it chokes 
                userstats.bestscore = tempgame.stats[i].score;
            }

            //code here to pass back new manipulated stats
        }
    });
}

一切正常,直到我嘗試在回調函數中使用tempgame對象。 它說“無法讀取未定義的屬性'得分'”。 這只是一個范圍問題嗎?

此外,我認為它可能是回調函數本身的問題。 也許循環會在回調運行之前遞增。 但即使在這種情況下,分數應該在那里它只會​​從錯誤的數組索引中拉出來......這就是讓我相信它可能只是一個范圍問題。

任何幫助將不勝感激。

你已經被臭名昭着的“ 循環中的定義函數 ”問題絆倒了。

改為使用“forEach”:

tempgame.stats.forEach(function (stat) {
    db.users.find({ username: stat.user }, function(err, res){
        if( err != null){
            //handle errors here.
        } else {
            var userstats = res[0].stats;
            if( stat.score > userstats.bestscore ){ //this is where it chokes 
                userstats.bestscore = stat.score;
            }

            //code here to pass back new manipulated stats
        }
    });
});

你的問題的一部分就像你在回答你的問題時所說的那樣,並且正如你所懷疑的那樣。 在調用回調之前, i變量正在改變。

問題的另一半是因為您的數據庫調用尚未返回。 由於NodeJS的異步特性,您的循環將在數據庫調用完成之前完成。 此外,您的數據庫調用不一定按照您調用它們的順序返回。 你需要的是像async.js這樣的流控制。 使用async.map將允許您並行地對數據庫進行所有調用,並在完成所有數據庫調用后將它們作為可以使用的值數組返回。

async.map(tempgame.stats, function(stat, callback){
  db.users.find({ username: stat.user }, function(err, res){
      if( err != null){
          callback(err);
      } else {
          callback(null, res[0].stats);
      }
  });      
}, function(err, stats){
  if(err){
    //handle errors
  } else{
    stats.forEach(function(stat){
      //do something with your array of stats
      //this wont be called until all database calls have been completed
    });
  }
});

除上述內容外,如果要將結果返回給應用程序,請http://nodeblog.tumblr.com/post/60922749945/nodejs-async-db-query-inside-for-loop

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM