2015-04-23 3 views
1

Ниже приведены мои множественные вызовы ajax с обещаниями.Получить ответ нескольких отложенных объектов в jQuery

$(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() возвращает мне некоторый баланс, который мне нужно суммировать, чтобы получить общее количество всех остатков. Но когда print console.log (balance) не предоставляет мне действительный массив баланса json. Еще одна проблема заключается в том, что если какой-либо из моих вызовов ajax в calculateApiBalances() терпит неудачу, он не печатает All Done. Что нужно сделать в приведенном выше коде для достижения этого.

+2

Прежде всего, [избегать отложенного антипаттера] (http://stackoverflow.com/q/23803743/1048572)! – Bergi

+0

Что должен содержать массив в случае ошибки? Обычно объединенное обещание просто отвергается. – Bergi

+0

@ Bergi. Исправлена ​​проблема с anitpattern. Я не забочусь о том, что какой-то аякс-вызов терпит неудачу. Мне нужно только учитывать баланс успешных вызовов ajax. Возможно ли это? – Vibhas

ответ

1

Но при печати console.log (balance) он не предоставляет мне действительный массив баланса json.

Это странная вещь $.when. Он не предоставляет вам массив, но вызывает ваш обратный вызов с несколькими аргументами.

Еще одна проблема: если какой-либо из моих вызовов ajax в вычисленииApiBalances() не удается, он не печатает 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); 
    })); 
} 

EDIT по 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 было успешным и сколько было неудачно, тогда есть еще несколько кодов для написания, но не много.

+0

@Roamer: Ах, я пропустил это требование, спасибо за его редактирование. Однако ваше редактирование находится на грани законности, как я могу его продвинуть? :-) – Bergi

+0

Берги, «край законности»? –

+0

Извините за нечетный термин, не родной спикер здесь.Я имел в виду, что редактирование было пограничным и, вероятно, не было бы принято в качестве предложения для редактирования («слишком резкое изменение», «попытка ответить»). Я в порядке, хотя, спасибо. – Bergi

Смежные вопросы