2012-06-07 24 views
13

Acabo de pasar 3 horas depurar un poco de código sólo para encontrar que fue causada por mí asumiendo que la orden de ejecución del siguiente código fue lineal: -

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

Ésta no es la primera vez que esto me ha causado problemas y me preguntaba cuál era la razón de este comportamiento.

¿Es para que cualquier solicitud de AJAX no contenga otra ejecución de scripts que puede no estar relacionada con la solicitud de AJAX?

+18

La primera 'A' en 'AJAX' significa asincrónico. – Gareth

+3

Puede establecer la opción 'async: true'. Las solicitudes sincrónicas pueden bloquear temporalmente el navegador, deshabilitando cualquier acción mientras la solicitud está activa. No recomendado. – jasssonpet

+0

@Gareth Sabía que la A representaba asincrónicamente, sin embargo, siempre pensé que esto se refería al hecho de que la solicitud se realiza sin "recargar" la página, es decir, hacer la solicitud http "principal" de nuevo, por lo tanto, la página es 'no sincronizado' con la solicitud http original que entregó la página. – rgvcorley

Respuesta

12

La mayoría de las otras respuestas están respondiendo a cómo lidiar con esto. Me gustaría ver, muy brevemente, en por qué asíncrono es bueno en este caso.

De hecho, más en el navegador Javascript es asíncrono. Tome, por ejemplo, este código:

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

¿Qué se ejecutará primero? No lo sabe, debido a la asincronicidad inherente al modelo de navegador (o, de hecho, a la mayoría de los códigos de eventos). Ejecuta código cuando ocurre un evento. Usted configura el documento, luego espera a que ocurra el evento, y su código podría ejecutarse en todo tipo de órdenes diferentes, dependiendo de qué eventos ocurran primero. El código JavaScript debe ejecutarse durante toda la vida de la página, no solo cuando se crea por primera vez.

en general La programación de Javascript (o al menos, la programación de Javascript más allá del nivel más simple) a menudo va a ser asincrónica. Además, tiene mucho sentido que las solicitudes HTTP sean asíncronas también.

Primero, como implica en su pregunta, hacer que el código sea sincrónico bloquearía la ejecución. Es decir, probablemente no desee hacer que una animación espere dos segundos para comenzar porque está haciendo una solicitud HTTP de dos líneas más adelante. Los tiempos de respuesta del servidor pueden ser (a) irregulares y (b) lentos, por lo que no tiene sentido que el diseño de su aplicación dependa de la velocidad de respuesta de su servidor.

En segundo lugar, y lo que es más importante, su usuario no va a dejar de usar la página porque la secuencia de comandos realiza una llamada AJAX. A su usuario no le importa A su usuario probablemente le importe que su comportamiento normal onscroll no funcione porque su secuencia de comandos está actualmente vinculada a una solicitud AJAX no relacionada. Para vincularse con la naturaleza asíncrona de toda la programación de JavaScript del navegador, la gran mayoría de las llamadas HTTP deben ser no bloqueantes, asincrónicas.

+0

Esta es la respuesta que estaba buscando, tienes razón, no estaba buscando soluciones al problema (era muy consciente de cómo hacer que la solicitud fuera sincrónica). Quería saber POR QUÉ era asincrónico, ¡así que muchas gracias! – rgvcorley

1

para sostener AJAX Finalización, hay que poner el código dentro de la función success:, como a continuación:

$.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 es una función asíncrona y, como tal, no espera a que la solicitud para completar, antes de regresar. En cambio, cuando la solicitud ha finalizado, llama a las funciones de devolución de llamada, especifique por success y/o error.

Si realmente necesita un bahgor sincrónico, puede establecer la opción async en falso. (ver docu). Pero en ese caso, tenga en cuenta que toda la interfaz de usuario se congela hasta que la solicitud finalice.

10

porque ajax es asincrónico. si se desea ejecutar algo en el éxito de la llamada AJAX, utilice el evento de éxito

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

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

Asynchronous medios?

asíncrono I/O, o de no bloqueo I/O, es una forma de entrada/salida procesamiento que permite otro procesamiento para continuar antes de la transmisión ha finished.Asynchronous I/O se utiliza para mejorar rendimiento, latencia y/o capacidad de respuesta.

+0

Bien, genial: sabía que la A representaba asincrónicamente, sin embargo, siempre pensé que esto se refería al hecho de que la solicitud se realiza sin "recargar" la página (es decir, hacer la solicitud http "principal" de nuevo), por lo tanto la página no está sincronizada con la solicitud http original que entregó la página. – rgvcorley

+0

generalmente las personas usan ajax para hacer actualizaciones parciales de páginas sin una recarga de página completa (puede haber visto en facebook, twitter, stackoverflow, etc.) para dar una buena experiencia de usuario – Shyju

+0

... pero eso no es lo que se refiere a los asincrónicos a – rgvcorley

1

Usted puede hacer el éxito o también puede usar .done();

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

Como los otros han dicho, ajax significa JavaScript asíncrono y XML. Dicho esto, se puede realizar una de las siguientes funciones con jquerys ajax:

  1. Establecer la opción "asíncrono" false, si desea que la llamada sea sincrónica. Esto es cierto por defecto. Ver los documentos. A partir de jQuery 1.8, el uso de esta propiedad está en desuso.

  2. Proporcionan una devolución de llamada "completa". Esto ocurrirá asincrónicamente de manera predeterminada. Esto es:

    Una función que se llamará cuando se ejecutan (después del éxito y devoluciones de llamada de error) finalizar la petición.

  3. Proporcionan una devolución de llamada "exitosa". Esto ocurrirá asincrónicamente de manera predeterminada.Esto es:

    Una función que debe invocarse si la solicitud se realiza correctamente.

+0

No estaba preguntando cómo hacer que la solicitud sea sincrónica. Me preguntaba POR QUÉ era asincrónico – rgvcorley

0

La primera A en AJAX significa asíncrono; eso significa que las llamadas AJAX se ejecutan en segundo plano y no detienen la ejecución del script hasta que finalizan. Esto es más o menos por diseño.

Si desea ejecutar código cuando la llamada termina, se puede pasar a una función en uno o más de los siguientes parámetros:

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

Para obtener más información, echa un vistazo a la API: http://api.jquery.com/jQuery.ajax

+0

OMG, otras 6 respuestas mientras escribía las mías ... –

2

jQuery $.ajax() proporciona 4 (eventos) opciones que puede usar: beforeSend, success, error y complete. Creo que en su caso, completo sería la respuesta correcta.

Por ejemplo

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

Otra opción es establecer simplemente asíncrono en false

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

De esta manera no se ejecutará su próximo estado hasta que se termine la declaración $ .ajax.

Cuestiones relacionadas