2013-02-26 8 views
10

szukam sposobu, aby zrobić zwrotnego po dwóch ajax połączeń ukończył:jquery odroczone - czekać aż dwa połączenia kompletny

$.when(
    call1(), 
    call2() 
).always(function() { 
    // Here I want to be sure the two calls are done and to get their responses 
); 

Połów jest, że jedno z połączeń może się nie powieść. Tak więc w moim kodzie zawsze się przywoływam, nie czekając na drugie połączenie.

Jak mogę czekać na wykonanie obu połączeń (sukces lub brak)?

+1

Możesz przyjrzeć się obietnicom http://api.jquery.com/promise/ – BlueBird

+0

@BlueBird: Jak? obiecuję wymagany obiekt jquery, którego nie mam. Czy możesz dodać przykład? – Naor

+1

@ BlueBird: '$ .when' już zwraca obiekt obietnicy, tj. OP już używa obietnic. –

Odpowiedz

11

Tutaj jest coś, co powinno wystarczyć:

$.whenAllDone = function() { 
    var deferreds = []; 
    var result = $.Deferred(); 

    $.each(arguments, function(i, current) { 
     var currentDeferred = $.Deferred(); 
     current.then(function() { 
      currentDeferred.resolve(false, arguments); 
     }, function() { 
      currentDeferred.resolve(true, arguments); 
     }); 
     deferreds.push(currentDeferred); 
    }); 

    $.when.apply($, deferreds).then(function() { 
     var failures = []; 
     var successes = []; 

     $.each(arguments, function(i, args) { 
      // If we resolved with `true` as the first parameter 
      // we have a failure, a success otherwise 
      var target = args[0] ? failures : successes; 
      var data = args[1]; 
      // Push either all arguments or the only one 
      target.push(data.length === 1 ? data[0] : args); 
     }); 

     if(failures.length) { 
      return result.reject.apply(result, failures); 
     } 

     return result.resolve.apply(result, successes); 
    }); 

    return result; 
} 

Wyjazd this Fiddle, aby zobaczyć jak to działa.

Zasadniczo czeka na wszystkich Odroczonych, bez względu na to, czy zawiodą, czy nie, i zbiera wszystkie wyniki. Jeśli mamy awarie, zwrócony Odroczony zakończy się niepowodzeniem z listą wszystkich niepowodzeń i rozwiązany z wszystkimi sukcesami w inny sposób.

+0

Dzięki. Miałem nadzieję, że jquery ma już na to rozwiązanie. – Naor

+0

Nie. Myślę, że częstszym przypadkiem jest to, że nie musisz czekać na zakończenie wszystkich Przeskoków, jeśli któryś z nich się nie powiedzie. – Daff

+0

Czy zatem słuszne jest założenie, że kolejność argumentów sukcesu jest taka sama jak kolejność dodanych odroczeń? argument [0] od dfd1? – DavidVdd

1

To nie jest ładne, ale możesz mieć globalną "ukończoną" zmienną dla każdego wywołania ajax, aby ustawić, kiedy kompletne. Każde wywołanie sprawdza również, czy obie zmienne zostały ustawione, a jeśli tak, zadzwoń zawsze.

0

Można również zagnieżdżać rozmowy:

$.when(call1()).always(function(){ 
    $.when(call2()).always(function(){ 
     // Here I want to be sure the two calls are done and to get their responses 
    }); 
}); 

Ale oczywiście oba połączenia staną się synchronicznie względem siebie.

Powiązane problemy