2017-01-01 76 views
-1

我想循環通過我從一個函數獲得的響應,並且數據存在於函數中,但在渲染代碼執行之前沒有足夠快地保存到數組,因此呈現一個空數組。是否有可能以某種方式等待循環結束或者是否有更有效的方法?使用控制檯日誌清除數組在我的res.send命令後被填充。循環不保存結果爲陣列異步問題?

router.get('/summoner/:playerName', function(req, res, next) { 
var summonerName = req.params.playerName; 
lolapi.Summoner.getByName(summonerName, function (error, summoner) { 

if (error) console.log('Summoner not Found!'); 
console.log(summoner); 

var summonerId = summoner[summonerName].id; 
var options = {beginIndex: 0, endIndex: 2}; 
var matchIds = []; 
var gameData = []; 
lolapi.MatchList.getBySummonerId(summonerId, options, function (error, matchlist) { 

    if (error) console.log('Summoner needs to play some games!'); 
    for (var i = 0; i < matchlist['matches'].length; i++) { 
    matchIds[i] = matchlist['matches'][i].matchId; 
    } 

    for (var i = 0; i < matchIds.length; i++) { 

    lolapi.Match.get(matchIds[i], function(error, game) { 
     // game variables is object format 
     gameData[i] = game; 
    }); 

    }; 
    // outputting array to browser but is empty 
    res.send(gameData); 
}); 
}); 

}); 

回答

3

是的,這是一個異步問題。通常dupetarget是How do I return the response from an asynchronous call?,它是值得一讀的答案在那裏,但你必須要對幾件事情在這裏,我認爲值得直接尋址:

lolapi.Match.get完成異步調用,所以:

  1. 您不能指望在for循環結束之前呼叫的回調已被呼叫(實際上,您保證它們不會被呼叫),並且

  2. i將不具有該值你希望它在保存到時有效,因爲在第一次回調發生之前它已經一直增加到matchIds.length

所以,你想有回調接近過其他的東西i,也有辦法來跟蹤你有多少回調得到(因爲他們可以不按順序發生,所以我們不能使用gameData.length):

router.get('/summoner/:playerName', function(req, res, next) { 
    var summonerName = req.params.playerName; 
    lolapi.Summoner.getByName(summonerName, function(error, summoner) { 

     if (error) console.log('Summoner not Found!'); 
     console.log(summoner); 

     var summonerId = summoner[summonerName].id; 
     var options = { 
      beginIndex: 0, 
      endIndex: 2 
     }; 
     var matchIds = []; 
     var gameData = []; 
     var received = 0;             // *** 
     lolapi.MatchList.getBySummonerId(summonerId, options, function(error, matchlist) { 

      if (error) console.log('Summoner needs to play some games!'); 
      for (var i = 0; i < matchlist['matches'].length; i++) { 
       matchIds[i] = matchlist['matches'][i].matchId; 
      } 

      for (var i = 0; i < matchIds.length; i++) { 
       getOne(i);             // *** 
      } 

      function getOne(index) {          // *** 
       lolapi.Match.get(matchIds[index], function(error, game) { // *** 
        // game variables is object format      // *** 
        gameData[index] = game;        // *** 
        if (++received === matchIds) {       // *** 
         // got all responses, we can output now   // *** 
         res.send(gameData);        // *** 
        }              // *** 
       });              // *** 
      }                // *** 
     }); 
    }); 

}); 

邊注:回覆這條線:

if (error) console.log('Summoner not Found!'); 

當然,你想return那裏(並可能發送一些東西通過res.send),而不是繼續與功能的邏輯?


附註2:您可以使用Array#forEach來做出簡單:

router.get('/summoner/:playerName', function(req, res, next) { 
    var summonerName = req.params.playerName; 
    lolapi.Summoner.getByName(summonerName, function(error, summoner) { 

     // *** Probably need to do more here on eror 
     if (error) console.log('Summoner not Found!'); 
     console.log(summoner); 

     var summonerId = summoner[summonerName].id; 
     var options = { 
      beginIndex: 0, 
      endIndex: 2 
     }; 
     lolapi.MatchList.getBySummonerId(summonerId, options, function(error, matchlist) { 

      // *** Probably need to do more here, or at least not continue 
      if (error) console.log('Summoner needs to play some games!'); 

      var gameData = []; 
      var received = 0; 
      matchlist.matches.forEach(function(entry, index) { // *** 
       lolapi.Match.get(entry.matchId, function(error, game) { 
        // game variables is object format 
        gameData[index] = game; 
        if (++received === matchlist.matches.length) { 
         // got all responses, we can output now 
         res.send(gameData); 
        } 
       }); 
      }); 
     }); 
    }); 

}); 
+0

是控制檯日誌只是有參考和調試也是我仍在學習JavaScript的,所以我不完全熟練的在它儘管如此,異步信息有趣的理解。謝謝yoyr筆記不好看看他們 – Elevant

+0

有了櫃檯是一個好主意,我沒有想到這個簡單的邏輯哈哈 – Elevant