我通过添加循环和Deferred对象来修改此example,以了解所有承诺已经完成。
我想要做的是将所有承诺推送到一个数组中,并在完成所有承诺时将它们打印出来。
这是我的代码:
POST https://www.test.com/rest.php HTTP/1.1
Host: api.test.com
Connection: keep-alive
Content-Length: 216
Origin: https://api.test.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36
Content-type: application/x-www-form-urlencoded
Accept: */*
Referer: https://api.test.com/nspcross.html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: CASLOGIN=true; CASLOGINSITE=1; LOGINACCSITE=1
nsp_svc=AppPromote.Developer.getRole&access_token=CFpS9d%2FDFoxQvOiM%2B%2F3j1iFce0dYDYQR0qq7TfAVUG5e%2FGhgBx2jHL6p8M02y09V%2FEHQpwemI7V1ACD32ERFD45678FGTHDBW3EI6iX4%3D&nsp_fmt=JSON&nsp_ts=18547841246
Fiddle获取完整代码
答案 0 :(得分:2)
来自MDN:
Promise.all (iterable)方法返回一个Promise,当可迭代参数中的所有promise都已解析或者iterable参数不包含promises时,它会解析。它拒绝承认拒绝的第一个承诺。
var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([p1, p2, p3]).then(values => {
console.log(values); // [3, 1337, "foo"]
});
答案 1 :(得分:2)
您的代码存在的问题是,在每个延迟完成后填充calls
数组。这意味着当您运行calls
时$.when.apply($, calls)
仍然为空,因此没有未完成的延迟,它将立即解决,直到任何呼叫实际完成。
您的代码也不必要地复杂化。正如已经提出的那样,使用Promise接口和Promise.all()
可以获得很多好处。在你的情况下,我会做这样的事情:
function get_data() {
var calls = [];
for (var j = 0, k = 5; j < k; j++) {
calls.push(get_result());
}
Promise.all(calls).then(function(results) {
console.log(results); // results is an array containing the result from each call.
});
}
无需检查承诺是否已解决,then
回调将在结算后被调用。如果承诺被拒绝,则应通过在promise链中的某处使用catch
回调来处理。这是承诺中唯一的两种可能结果。
P.S。您的代码的另一个问题是您始终将循环中创建的最后一个延迟推送到calls
数组。这是因为d
的范围在for循环之外,然后在每次迭代中重新分配,并且在异步调用解析时,它已被分配了最终的延迟。