以下是我承诺的多个ajax调用。
$(window).load(function(){
$.when(getApiModemList()).done(function(vendors){
var deferreds = calculateApiBalances(vendors);
$.when.apply($,deferreds).done(function(balance) {
console.log(balance);
console.log("All Done");
});
});
function getApiModemList(){
return $.getJSON("url");
}
function calculateApiBalances(vendors)
{
var defer=[];
$.each(vendors,function(k,v){
defer.push($.getJSON(someurl));
});
return defer;
}
});
函数calculateApiBalances()返回一些余额,我需要总结以获得所有余额的总和。 但是当打印console.log(balance)时它没有为我提供有效的json数组。 另一个问题是,如果我在calculateApiBalances()中的任何一个ajax调用失败,它就不会打印All Done。 在上面的代码中应该做些什么来实现这一点。
答案 0 :(得分:1)
但是当打印console.log(balance)时,它没有为我提供有效的余量json数组。
这是$.when
的奇怪之处。它没有为您提供数组,但使用多个参数调用您的回调。
另一个问题是,如果我在calculateApiBalances()中的任何一个ajax调用失败,它就不会打印All Done。
是的,因为当一个承诺失败时,整个$.when()
承诺会立即被拒绝,并且您没有任何错误处理程序。如果您想要总是获得一个数组(可能无效的响应),您必须单独捕获错误。另请参阅$.Deferred: How to detect when every promise has been executed。
在上面的代码中应该做些什么来实现这一点。
首先,avoid the deferred antipattern: - )
$(window).load(function() {
getApiModemList().then(calculateApiBalances).then(function() {
var balance = Array.prototype.slice.call(arguments);
console.log(balance);
console.log("All Done");
});
});
function getApiModemList() {
return $.getJSON(somurl).then(function(res) {
return res.data;
});
}
function calculateApiBalances(vendors) {
return $.when.apply($, $.map(vendors, function(v, k) {
return $.getJSON(someurl).then(null, $.when);
}));
}
Roamer编辑:
这是主程序的一个版本,它有一个总结天平的机制。
getApiModemList().then(calculateApiBalances).then(function() {
var sumOfBalances = Array.prototype.reduce.call(arguments, function(tot, obj) {
return tot + (+obj.balance || 0);
}, 0);
console.log(sumOfBalances);
console.log("All Done");
});
obj
是$.getJSON(someurl)
中calculateApiBalances()
承诺的对象。在$.getJSON()
错误的情况下,obj
将是jqXHR对象,obj.balance
将是undefined
而+obj.balance
将是NaN
,因此默认加零;否则添加obj.balance
。
如果你想知道有多少getJSON请求是成功的,有多少是不成功的,那么还有更多的代码需要编写,但不是很多。