在jquery中获取多个延迟对象的响应

时间:2015-04-23 07:08:37

标签: javascript jquery ajax promise jquery-deferred

以下是我承诺的多个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。 在上面的代码中应该做些什么来实现这一点。

1 个答案:

答案 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请求是成功的,有多少是不成功的,那么还有更多的代码需要编写,但不是很多。