2012-06-07 7 views
13

Ho appena trascorso 3 ore il debug di un po 'di codice solo per scoprire che è stato causato da me dal presupposto che l'ordine di esecuzione del seguente codice era lineare: -

$.ajax({ajax options}); 
console.log('I was assuming this would execute once the ajax request was complete'); 

Questa non è la prima volta che questo mi ha causato problemi e mi stavo chiedendo quale fosse la ragione di questo comportamento?

È così che qualsiasi richiesta Ajax non regge altre esecuzioni di script che potrebbero non essere correlate alla richiesta Ajax?

+18

Il primo 'A' in' AJAX' sta per asincrono. – Gareth

+3

È possibile impostare l'opzione 'async: true'. Le richieste sincrone possono bloccare temporaneamente il browser, disabilitando tutte le azioni mentre la richiesta è attiva. Non consigliato. – jasssonpet

+0

@Gareth Ero consapevole del fatto che A fosse acronimo asincrono, tuttavia ho sempre pensato che questo si riferisse al fatto che la richiesta è stata fatta senza "ricaricare" la pagina, cioè facendo di nuovo la richiesta http "genitore", quindi la pagina è quindi 'non sincronizzato' con la richiesta http originale che ha consegnato la pagina. – rgvcorley

risposta

12

La maggior parte delle altre risposte sta rispondendo come comportarsi in questo modo. Mi piacerebbe guardare, molto brevemente, a perché asincrono è buono in questo caso.

In effetti, più nel browser Javascript è asincrono. Prendi, ad esempio, questo codice:

document.getElementById('foo').onclick = function() { 
    alert('foo clicked'); 
}; 
document.getElementById('bar').onclick = function() { 
    alert('bar clicked'); 
}; 

Quale sarà il primo? Non lo sai, a causa dell'asincronicità inerente al modello del browser (o di fatto alla maggior parte dei codici basati sugli eventi). Esegui il codice quando si verifica un evento. Si imposta il documento, quindi si attende che l'evento si verifichi e il codice può essere eseguito in tutti i tipi di ordini diversi, a seconda di quali eventi si verificano per primi. Il codice Javascript deve essere eseguito durante l'intero ciclo di vita della pagina, non solo quando viene creato per la prima volta.

Quindi in generale La programmazione Javascript (o almeno la programmazione Javascript oltre il livello più semplice) è spesso asincrona. Inoltre, è molto sensato che le richieste HTTP siano asincrone.

In primo luogo, come si implica nella sua interrogazione, rendendo il codice sincrono potrebbe bloccare l'esecuzione. Vale a dire, probabilmente non vuoi fare un'animazione aspettare due secondi per iniziare perché stai facendo una richiesta HTTP due righe più in alto. I tempi di risposta del server possono essere (a) irregolari e (b) lenti, quindi non ha senso che il design dell'applicazione dipenda dalla velocità della risposta del server.

In secondo luogo, e cosa ancora più importante, l'utente non ha intenzione di smettere di usare il pagina perché lo script sta facendo una chiamata AJAX. Il tuo utente non si cura. Il tuo manuale sarà probabilmente la cura che il vostro normale onscroll comportamento non funziona perché lo script è attualmente legato con una richiesta AJAX non correlato. Per legare alla natura asincrona dell'intera programmazione Javascript del browser, la stragrande maggioranza delle chiamate HTTP dovrebbe essere non bloccante, asincrona.

+0

Questa è solo la risposta che stavo cercando - hai ragione io Non stavo cercando soluzioni al problema (ero ben consapevole di come rendere la richiesta sincrona) volevo sapere PERCHÉ era asincrono, quindi grazie mille! – rgvcorley

1

di contenere fino AJAX completamento, è necessario inserire il codice all'interno success: funzione come di seguito:

$.ajax({ 
    url: 'ajax/test.html', 
    success: function(data) { 
    // Do something after AJAX is completed. 
    console.log('I was assuming this would execute once the ajax request was complete'); 
    } 
}); 
0

$.ajax è una funzione asincrona e come tale non aspetta per la richiesta di completare, prima di tornare. Invece, al termine della richiesta, chiama le funzioni di callback, specificate per success e/o error.

Se è veramente necessario un bahviour sincrono, è possibile impostare l'opzione async su falso. (vedi docu). Ma in tal caso sappi che l'intera interfaccia utente si blocca fino a quando la richiesta non è terminata!

10

perché ajax è asincrono. se si desidera eseguire qualcosa sul successo della chiamata ajax, utilizzare l'evento di successo

$.ajax({ 
    url: 'yourserverpage.php', 
    success: function(data) { 

    alert('This will be executed only when ajax call is success /finished'); 
    } 
}); 

Asynchronous mezzi?

I/O asincrono, o non-blocking I/O, è una forma di input/output elaborazione che consente altre elaborazioni di continuare la trasmissione prima ha finished.Asynchronous I/O viene utilizzato per migliorare rendimento, latenza e/o reattività.

+0

Ok, fantastico: ero consapevole del fatto che A fosse acronimo asincrono, tuttavia ho sempre pensato che ciò si riferisse al fatto che la richiesta è stata fatta senza "ricaricare" la pagina, (cioè rendendo di nuovo la richiesta HTTP "genitore") la pagina viene quindi "non sincronizzata" con la richiesta http originale che ha consegnato la pagina. – rgvcorley

+0

di solito la gente usa ajax per fare aggiornamenti parziali delle pagine senza una pagina di ricarica completa (potresti aver visto in facebook, twitter, stackoverflow ecc.) Per dare una bella esperienza utente – Shyju

+0

... ma non è quello che si riferisce asincrono a – rgvcorley

1

Si può fare successo o si può anche utilizzare .done();

$.ajax({ajax options}).done(console.log('I was assuming this would execute once the ajax request was complete')); 
0

Come gli altri hanno detto, l'Ajax sta per Asynchronous JavaScript and XML. Detto questo, si può fare una delle seguenti operazioni con jquerys ajax funzione:

  1. Impostare l'opzione "async" per falso, se si desidera che la chiamata ad essere sincrona. Questo è vero per impostazione predefinita. Vedi i documenti. A partire da jQuery 1.8, l'uso di questa proprietà è deprecato.

  2. Fornire un callback "completo". Ciò avverrà in modo asincrono per impostazione predefinita. Questo è:

    Una funzione da chiamare quando termina la richiesta (dopo il successo e vengono eseguite le richiamate di errore ).

  3. Fornire un callback "riuscito". Ciò avverrà in modo asincrono per impostazione predefinita.Questo è:

    Una funzione da chiamare se la richiesta ha esito positivo.

+0

Non stavo chiedendo come fare la richiesta sincrona - stavo chiedendo PERCHÉ era asincrono – rgvcorley

0

Il primo Un in AJAX acronimo di Asynchronous ; ciò significa che le chiamate AJAX vengono eseguite in background e non ritardano l'esecuzione dello script finché non sono terminate. Questo è più o meno dal design.

Se si desidera eseguire del codice quando la chiamata termina, è possibile passare una funzione in uno o più dei seguenti parametri:

$.ajax({ 
    // your other options 

    done: function(data, textStatus, jqXHR) { 
    alert('Success! I got the following data back: ' + data); 
    // this runs when the request has finished successfully 
    }, 

    fail: function(jqXHR, textStatus, errorThrown) { 
    alert('Oops, there was an error :('); 
    // this runs when the request has finished, but with an error 
    }, 

    always: function(jqXHR, textStatus) { 
    alert("OK, I'm done."); 
    // this runs when the call is finished, regardless 
    // of whether it has succeeded or not 
    } 

Per maggiori informazioni, visitate l'API: http://api.jquery.com/jQuery.ajax

+0

OMG, altre 6 risposte mentre stavo scrivendo il mio ... –

2

jQuery $.ajax() fornisce 4 opzioni (eventi) che è possibile utilizzare: beforeSend, buon fine, errore, e completi. Penso che nel tuo caso, completo sarebbe la risposta giusta.

Per esempio

$.ajax({ 
    url: someUrl, 
    //... 
    beforeSend: function(){ 
    console.log("I'm sending AJAX."); 
    //display loading? 
    }, 
    success: function(data){ 
    console.log('response: '+data); 
    }, 
    error: function(er){ 
    console.log(er.responseText); 
    }, 
    complete: function(){ 
    console.log("I'm done."); 
    //hide loading? 
    } 
}); 
0

Un'altra opzione è quella di impostare semplicemente async su false

$.ajax({ 
    async : 'false', 
    other options 
}); 

In questo modo non verrà eseguita la tua prossima dichiarazione fino a quando l'istruzione $ .ajax è finito.

Problemi correlati