在循环中等待嵌套的 Promise
Posted
技术标签:
【中文标题】在循环中等待嵌套的 Promise【英文标题】:Wait for nested promise in a loop 【发布时间】:2017-12-23 03:05:45 【问题描述】:我从公共 API 获取数据,需要了解中间调用以构建最后一个相关调用。
但是,我无法构建一个在何时且仅在最终调用完成时才解决的 Promise。
我试图“链接”这些调用,每个调用都返回一个更深一层的 Promise,但是,填充表格的主要 Promise 仍然在第一次调用完成时解析(因此,数据还没有被推送到'results'数组中,表格无法填满)。
你能帮我解决这个问题吗?
(旁注:您可能已经理解,我是初学者,因此欢迎对代码提出任何一般性建议/评论)。
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>
【问题讨论】:
你似乎混合了很多东西,有很多函数实际上从 ajax 调用返回 jQuery Deferred 对象,然后是嵌套调用、循环、数组等。一般来说,你应该尝试$.when.apply($, promises).then(...
而不是 Promise.all
【参考方案1】:
将.done
更改为.then
已解决。
【讨论】:
以上是关于在循环中等待嵌套的 Promise的主要内容,如果未能解决你的问题,请参考以下文章