2013-02-26 15 views
10

Sto cercando un modo per fare una richiamata dopo due chiamate ajax completa:jquery differita - attendere fino a due chiamate completa

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

Il problema è che una delle chiamate potrebbe non riuscire. Quindi, nel mio codice, invocherò sempre senza aspettare l'altra chiamata.

Come è possibile attendere il completamento di entrambe le chiamate (esito positivo o negativo)?

+1

Si consiglia di esaminare le promesse http://api.jquery.com/promise/ – BlueBird

+0

@BlueBird: come? promesso richiesto oggetto jQuery che non ho. Puoi aggiungere un esempio? – Naor

+1

@BlueBird: '$ .when' restituisce già un oggetto promessa, vale a dire che l'OP utilizza già delle promesse. –

risposta

11

Qui è qualcosa che dovrebbe fare il trucco:

$.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; 
} 

Partenza this Fiddle per vedere come funziona.

In sostanza, attende che tutti i differiti finiscano, non importa se falliscono o meno e raccoglie tutti i risultati. Se abbiamo fallimenti, il Deferred restituito fallirà con un elenco di tutti i fallimenti e risolverà con tutti i successi in caso contrario.

+0

Grazie. Speravo che jquery avesse già una soluzione per questo. – Naor

+0

No. Penso che il caso più comune sia che non è necessario aspettare che tutti i differiti finiscano se qualcuno di essi fallisce. – Daff

+0

Quindi è corretto assumere che l'ordine degli argomenti di successo sia lo stesso dell'ordine dei differiti aggiunti? argomento [0] da dfd1? – DavidVdd

1

Non è bello, ma è possibile avere una variabile "completata" globale per ogni chiamata ajax da impostare al termine. Ogni chiamata controllerebbe anche se entrambe le variabili erano state impostate, e in tal caso, chiama la tua funzione sempre.

0

È anche possibile nidificare le chiamate:

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

Ma naturalmente le due chiamate diventerà sincrono gli uni agli altri.

Problemi correlati