简体   繁体   中英

Wait for nested promise in a loop

I am getting data from a public API and need knowledge of the intermediate calls to build the last, relevant call.

However, I can't get to build a promise that resolves when, and only when the final call has been made.

I have tried to 'chain' the calls, each one of them returning a promise one layer deeper, however, the main promise, that fills the table, still resolves when the first call is done (as a consequence, the data has not been pushed to the 'results' array yet, and the table cannot be filled).

Could you please help me figure this out?

(Side note: As you may have understood, I am a beginner, so any general advice/comment on the code is welcome).

 let results = []; function getData() { results = []; let promises = []; for (var i = 1; i < 2; i++) { let rankNbr = 1 //For consistency (Math.floor(Math.random() * 99) + 1)*i let data = { 'api_key': 'd6207c18cd4c8980bcab7c7f21b60172', 'metric': 'dps', 'difficulty': 4, 'class': 9, 'spec': 1, 'limit': 1, 'page': rankNbr } promises.push($.get("https://www.warcraftlogs.com/v1/rankings/encounter/2037", data).done(function(data) { //Most of the time only one report, but it might be more in the future var loopPromises = [] for (var i = 0; i < data.rankings.length; i++) { loopPromises.push(getEQpct(data.rankings[i], rankNbr)); } return Promise.all(loopPromises) })); } Promise.all(promises).then(function() { alert(results.length); for (var i = 0; i < results.length; i++) { var row = document.createElement("tr"); var nameCell = document.createElement("td"); row.appendChild(nameCell); nameCell.innerText = results[i].name; var reportIDCell = document.createElement("td"); row.appendChild(reportIDCell); reportIDCell.innerText = results[i].reportID; var rankCell = document.createElement("td"); row.appendChild(rankCell); rankCell.innerText = results[i].rankNbr; var EQPctCell = document.createElement("td"); row.appendChild(EQPctCell); EQPctCell.innerText = results[i].EQPercent; $("#resultsTable>tbody").append(row); } }); } function getEQpct(ranking, rankNbr) { let fightData = { 'api_key': 'd6207c18cd4c8980bcab7c7f21b60172', 'translate': false } return $.get("https://www.warcraftlogs.com:443/v1/report/fights/" + ranking.reportID, fightData).done(function(data) { let damagedata = { 'api_key': 'd6207c18cd4c8980bcab7c7f21b60172', 'start': data.fights[ranking.fightID - 1].start_time, //ID #1 is in 0th position in the array. 'end': data.fights[ranking.fightID - 1].end_time, 'filter': "source.name='" + ranking.name + "'", 'translate': false } return $.get("https://www.warcraftlogs.com:443/v1/report/tables/damage-done/" + ranking.reportID, damagedata).done(function(data) { let totalDamage = data.entries[0].total; let EQDamage; try { EQDamage = data.entries[0].abilities.filter(function(ability) { return ability.name == "Earthquake" })[0].total; } catch (err) { EQDamage = 0; } let SSDamage; try { SSDamage = data.entries[0].abilities.filter(function(ability) { return ability.name == "Seismic Lightning" })[0].total; } catch (err) { SSDamage = 0; } ranking.EQPercent = (EQDamage + SSDamage) / totalDamage * 100; ranking.rankNbr = rankNbr results.push(ranking); }); }); } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button onclick="getData()">getData</button> <table id="resultsTable"> <thead> <th>Name</th> <th>ReportID</th> <th>Rank</th> <th>EQ pct</th> </thead> <tbody></tbody> </table> 

更改.done.then已经解决了这个问题。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM