2015-06-15 2 views
4

Я просмотрел много похожих вопросов, но предлагаемые решения не работают во всех случаях, как ожидалось. Следующий код работает прекрасно, когда все Ajax звонки успешно сделано, но если какой-либо из Ajax вызовов происходит сбой, то onComplete сразу же называют:Дождитесь завершения всех вызовов jQuery ajax (сделано или отклонено)

var deferredArray = $('.preload').map(function() { 
    return $.get(this.href) 
}); 
$.when.apply($, deferredArray).then(onComplete, onComplete); 

Так что может быть два случая:

  • все отсроченные звонки успешны, затем onComplete называется впоследствии - работает нормально;
  • некорректный отложенный вызов (возвращает HTTP 400 Bad request), то onComplete вызывается немедленно, не дожидаясь других отложенных вызовов.

Второй случай представляет мою проблему. Он должен всегда ждать завершения всех вызовов независимо от состояния, прежде чем звонить onComplete.

Я использую jQuery 1.7.1, поскольку он встроен в фреймворк. Если проблема связана с версией, я могу обновить ее, но я бы предпочел сохранить текущую версию.

+0

Вы смотрели в http://api.jquery.com/ajaxcomplete/? –

+0

@ KrisHollenbeck, но событие ajaxComplete запускается по каждому завершенному запросу Ajax. Мне нужно, чтобы это срабатывало только один раз, когда все мои запросы Ajax завершены. Вот почему я должен использовать 'when'. – lagivan

+0

Извините, я хотел опубликовать ссылку 'ajaxStop()'. Я использовал 'ajaxStop()' для запуска файла после завершения всех событий ajax. Обычно это работает, если мне нужно выполнить какую-то работу с JavaScript, связанную с компоновкой, и обеспечить, чтобы данные были на месте. Но это может не сработать для вашего случая использования. https://api.jquery.com/ajaxStop/ –

ответ

2

Вы можете попробовать ajaxStop(). Все это не самое элегантное решение.

$(document).ajaxStop(function() { 
    // do some stuff now that all the ajax stuff has stopped 
}) 

Также обратите внимание:

Если $.ajax() или $.ajaxSetup() вызывается с глобальным параметром, установленным в ложь, метод .ajaxStop() не будет срабатывать.

2

Я не уверен, что это за пределами тех видов решений, которые вы ищете, но я недавно воспользовался bluebird.js, чтобы обернуть все мои jquery-вызовы ajax.

Например:

Promise.resolve($.get("http://www.google.com")).then(function() {}); 

Что это позволяет мне делать затем выполнить Promise.all, который будет ждать всех Аякса вызовов будет завершена. Каждое индивидуальное обещание может пройти или потерпеть неудачу, но .then (или .spread) на .all будет вызываться только в том случае, если все они преуспеют.

var aPass = function(){ 
    return Promise.resolve($.get("/echo/json/")) 
}; 

var aFail = function(){ 
    return Promise.resolve($.get("/echo/jsonFake/")) // this will fail 
}; 

var allPass = [aPass(), aPass(), aPass()]; 

var oneFails = [aPass(), aPass(), aFail()]; 


Promise.all(allPass).spread(function(a,b,c){ 
    console.log("All Done!"); 
}).catch(function(){ 
    console.log("NEVER FAILS!"); 
});; 

Promise.all(oneFails).spread(function(a,b,c){ 
    console.log("never goes in here"); 
}).catch(function(){ 
    console.log("FAILED"); 
}); 

Вот это jsfiddle демонстрирует это: http://jsfiddle.net/ys598t4s/2/