2011-11-11 18 views
5

Sto usando jQuery e ho un ciclo di richieste AJAX asincrone. So che posso aspettare che finiscano tutti usando il pratico metodo $ .when.apply (array_of_requests) .then() '.Come attendere fino alla nidificazione asincrona jQuery Le richieste AJAX sono finite?

Ma ho anche un'altra serie di richieste AJAX che vengono eseguite solo dopo che ciascuna delle prime richieste è terminata. Voglio aspettare che finiscano anche loro, ma non sono sicuro al 100% di aver trovato il modo migliore.

Ecco un esempio semplificato di mie richieste:

var intital_data = [1,2,3,4,5,6,7,8,9,10]; 
var promises = []; 
var promises_inner = []; 

$.each(intitial_data, function(i, n) { 
    var ajax_call = $.ajax({url:'http://www.domain.com/etc/'+n}); 
    promises.push(ajax_call); 

    ajax_call.done(function(data) { 
     var ajax_call_inner = $.ajax({url:'http://www.domain.com/etc/'+data.result}); 
     promises_inner.push(ajax_call_inner); 

     ajax_call_inner.done(function(data) { 
      // Do something with the content of data here. 
     }); 
    }); 
}); 

Così, quando ciascuno dei dieci cappio richieste AJAX è fatto, faccio una seconda richiesta AJAX sulla base dei risultati della prima. Tutto funziona bene

Ho poi avere qualcosa di simile, perché voglio aspettare fino a quando entrambi i primi dieci richieste (memorizzato nella matrice promesse) e il secondo lotto (memorizzato in promises_inner) sono completate:

$.when.apply($, promises).then(
    function() { 
     // The ten outer AJAX calls are finished now. 

     $.when.apply($, promises_inner).then(
      function() { 
       // The inner AJAX calls are finished now. 
      } 
     ); 
    } 
); 

All'interno della prima funzione $ .when.apply(). Then() 'done' il secondo lotto di richieste non è ancora stato completato, o addirittura aggiunto alla matrice promises_inner. Ma ho trovato che aggiungere $ .when.apply(). Then() sembra funzionare - all'interno della sua funzione 'done' all le richieste sono finite.

Ma non sono sicuro che questa sia la soluzione migliore e più robusta. Sono preoccupato che funzioni solo per coincidenza - che sta causando solo un ritardo sufficiente per il completamento delle chiamate - piuttosto che avere un senso logico.

C'è una soluzione migliore, più solida come una roccia? Grazie.

+0

ho parlato troppo presto, quando ho detto che sembra funzionare. a volte funziona, ma altre volte, promises_inner non ha avuto tutto il annuncio di query AJAX annidato ded a esso ancora. Così a volte il $ interiore. Quando accade prima che tutto sia stato restituito. –

risposta

2

Dai un'occhiata a $ .Callbacks in 1.7. Penso che sarai entusiasta della flessibilità di creare i tuoi "flussi" e la possibilità di riutilizzarli, eseguirli una volta, ecc.

Non c'è niente di sbagliato in quello che hai fatto (il modello di applicazione potrebbe non essere una prima scelta di più, di solito li elencano solo in $ .quando (a, b, c ....) - ma potresti preferire la sintassi migliore di $ .Callbacks

+0

Grazie per il puntatore. I documenti $ .Callbacks mi fanno male al cervello ma mi aspetto che alla fine possa affondare! Nel frattempo, pensi che il mio $ annidato ... quando ... dovrebbe essere affidabile? –

+0

Dobbiamo fare cose simili quando elaboriamo le regole nella nostra app di assicurazione perché ci sono almeno 10 servizi coinvolti. L'altra cosa che puoi fare, che può essere più facile da leggere, è creare un rinvio e risolverlo solo quando il primo è completato. Usa quella promessa di Deferred come il .done per il prossimo gruppo di callback. Addy Osmani ha un buon articolo sui callback e probabilmente ne arriveranno altri. – AutoSponge

0

Prova questo con una sola promessa principale per fullfill (risolvere) per loop-run (qui ancora chiamato inner_promise).

var initial_data = [1,2,3,4,5,6,7,8,9,10]; 
var promises_inner = []; 

initial_data.forEach(function(n) { 
    // Create promise for the inner call here. 
    var promise_inner = $.Deferred(); 
    promises_inner.push(promise_inner); 

    $.ajax({url:'http://www.domain.com/etc/'+n}).done(function(data) { 
     $.ajax({url:'http://www.domain.com/etc/'+data.result}).done(function(data) { 
      // Do something with the content of data here. 
      promise_inner.resolve(); 
     }); 
    }); 
}); 
console.log("promises_inner contains " + promises_inner.length + " promises") // should contain all the 10 promises 

$.when.apply($,promises_inner).done(function() { 
    // The inner AJAX calls are finished now 
}) 
Problemi correlati