2015-02-25 15 views
5

Ho il seguente scenario nel mio javascript:Come attendere gestore successo ajax per terminare prima di eseguire un'altra

  1. Ajax carica un record.
  2. In base al valore di ritorno di tale record, un'altra chiamata ajax acquisisce un modulo html che viene aggiunto al DOM
  3. Al termine # 2, i record ottenuti dal numero 1 vengono quindi caricati nel modulo creato in # 2.

Sto usando il when in modo che quando # 2 è completo, posso caricare i valori del modulo da # 1. Il problema è che sembra che quando non aspetta che il gestore di successo finisca, solo la chiamata ajax stessa. Devo aspettare che la funzione di successo n. 2 sia completata (poiché questo è ciò che ha creato il modulo nel DOM) prima di poter continuare a caricare il modulo con i valori.

Se aggiungo un alert1 al passo # 2, funziona (che sto cercando di indovinare è perché è in attesa per l'avviso per essere cliccato, e in quel tempo, il gestore di successo è terminato.

+0

si può usare 'successo()' piuttosto che 'quando '?, non' quando' aspetta solo un ritorno piuttosto che un ritorno positivo? – atmd

+0

mi sembra che anche il n. 2 debba fare il n. 3 – jcuenod

+0

Si prega di mostrare l'esempio di codice – charlietfl

risposta

3

Do qualcosa come questo in cui si utilizza funzioni annidate nella success callback:

$.ajax({ 
    url: "somewhere" 
    success: function(data1){ 
     //Use data1 to determine ajax request #2 
     $.ajax({ 
      url: "somewhere else" 
      success: function(data2){ 
       //Do stuff with data1 and data2 
      } 
     }); 
     } 
}); 
+1

Ciò annulla lo scopo di asincronicamente. Stai facendo una richiesta dopo la precedente restituisce. –

+0

Grazie. In realtà funziona, tuttavia ho il mio secondo ajax all'interno di una funzione (dato che lo uso in più posti), quindi 'data' non sarà disponibile. A meno che non lo passi come parametro opzionale.? – Lock

+0

@Jose Rui Santos No ... la seconda richiesta non può essere effettuata senza informazioni dal primo (come indica la domanda). Ha ancora senso farlo in modo asincrono come gli altri JS sulla pagina possono continuare a funzionare (per fare cose come gestire l'interfaccia utente) senza essere bloccati da queste chiamate – winhowes

1

È possibile utilizzare jQuery promesse, vale a dire:

var loadingData = $.get(loadDataUrl); 
var loadingHtml = $.get(grabHtmlUrl); 
$.when(loadingData, loadingHtml).done(function(loadDataResult, loadHtmlResult){ 
    //add the html to the dom 
    //use data to update the dom as you please  
}); 

Nota: $ .g et è solo una versione di $ .ajax che esegue una richiesta GET

Fonti: http://api.jquery.com/deferred.promise/

http://api.jquery.com/jquery.get/

http://api.jquery.com/jquery.ajax/

http://api.jquery.com/jquery.when/

1

Si dovrebbe usare when o success non entrambi. Sembra (anche se gli esempi di codice renderebbero questo più chiaro) si stanno allegando due ascoltatori separati alla chiamata ajax, ma si desidera eseguire solo uno dopo l'altro.
Mi piacerebbe uno rotolo sia in un unico evento come:

$.ajax(... , function(){ 
    // success 
    // prep stuff here 
    $.ajax(... , function(){ 
     // second success 
     // do final stuff here 
    }); 
}); 

o avvolgere si chiama Ajax all'interno di un'altra promessa (questo può richiedere un po 'di più la lettura intorno promesse jQuery).

Ma se fai qualcosa come

$.when($.ajax(... , function(){ 
    // thing a 
}).then(function(){ 
    // thing b 
}); 

Thing a e b eseguirà allo stesso tempo, perché sono progettati per più o meno la stessa cosa.

+1

poiché '$ .ajax()' restituisce una promessa, non è necessariamente necessario avvolgerla in '$ .when'. '$ .ajax(). then (function() {})' andrebbe bene. –

+0

Molto vero, ma come la domanda specificamente menzionata "quando" ho pensato di aggiungerla. – Ben

0

po 'tardi per rispondere, ma

Molto meglio modo è quello di utilizzare le promesse, come il modo in cui designed to be used

Pseudo implementazione

var promise = $.ajax({ 
    url: url, 
    data: data 
}).done(function (data) { 
    var result = process(data); 
    return $.ajax({ 
     url: url, 
     data: result 
    }); 
}).done(function (data) { 
    // data is the result of second ajax call 
}); 
Problemi correlati