2010-07-11 12 views
35

la cuestión es bastante simple y técnica:JavaScript: Las variables globales después de peticiones Ajax

var it_works = false; 

$.post("some_file.php", '', function(data) { 

    it_works = true; 

}); 

alert(it_works); # false (yes, that 'alert' has to be here and not inside $.post itself) 

Lo que quiero lograr es:

alert(it_works); # true 

¿Hay una manera de hacer eso? Si no, ¿puede $.post() devolver un valor que se aplicará a it_works?

+3

Ver http://stackoverflow.com/questions/133310/how-can-i-get-jquery-to-perform-a-synchronous-rather-than-asynchronous-ajax-req –

Respuesta

69

Lo que espera es el sincrónica (bloqueo) Tipo de solicitud.

var it_works = false; 

jQuery.ajax({ 
    type: "POST", 
    url: 'some_file.php', 
    success: function (data) { 
    it_works = true; 
    }, 
    async: false // <- this turns it into synchronous 
});​ 

// Execution is BLOCKED until request finishes. 

// it_works is available 
alert(it_works); 

Las solicitudes son asíncrono (no bloqueante) por defecto lo que significa que el navegador no esperar a que se completarán con el fin de continuar su labor. Es por eso que su alerta obtuvo un resultado incorrecto.

Ahora, con jQuery.ajax puede configurar opcionalmente la solicitud para ser sincrónica, lo que significa que el script sólo continuará funcionando después de la solicitud está terminado.


La forma RECOMENDADO, sin embargo, es refactor su código para que los datos se pasan a una función de devolución de llamada tan pronto como la petición está terminado. Esto se prefiere porque bloquear la ejecución significa bloquear la UI que es inaceptable. Hacerlo de esta manera:

$.post("some_file.php", '', function(data) { 
    iDependOnMyParameter(data); 
}); 

function iDependOnMyParameter(param) { 
    // You should do your work here that depends on the result of the request! 
    alert(param) 
} 

// All code here should be INDEPENDENT of the result of your AJAX request 
// ... 

asíncrono programación es un poco más complicada porque la consecuencia de hacer una solicitud se encapsula en una función en lugar de seguir el estado de la solicitud. Pero el comportamiento en tiempo real que las experiencias de los usuarios pueden ser significativamente mejor porque no van a ver a un servidor de red lento o débil que el navegador a actuar como si se hubiera estrellado. La programación sincrónica es irrespetuosa y no debe emplearse en aplicaciones que son utilizadas por personas.

Douglas Crockford(YUI Blog)

+0

Mi malo, vencerme a eso. – mattbasta

+0

@mattbasta no hay problema :) – galambalazs

+3

Pero tenga en cuenta que esto matará la usabilidad si 'some_file.php' preforma operaciones mucho (costosas). –

4

Parece que su problema es simplemente un problema de concurrencia. La función de publicación toma un argumento de devolución de llamada para avisarle cuando la publicación haya finalizado. No puede hacer la alerta en un ámbito global como este y esperar que la publicación ya haya finalizado. Tienes que moverlo a la función de devolución de llamada.

6

AJAX significa Asynchronous JavaScript y XML. Por lo tanto, la publicación en el servidor no está sincronizada con el resto de la función. Pruebe un código como este en su lugar (simplemente rompe la abreviatura $.post en la llamada más larga $.ajax y agrega la opción async).

var it_works = false; 

$.ajax({ 
    type: 'POST', 
    async: false, 
    url: "some_file.php", 
    data: "", 
    success: function() {it_works = true;} 
}); 

alert(it_works); 

Hope this helps!

3

El motivo por el que su código falla es porque post() iniciará una solicitud asynchronous al servidor. Lo que eso significa para usted es que post() devuelve inmediatamente, no después de que la solicitud se complete, como está esperando.

Lo que necesita, entonces, es que la solicitud sea sincrónica y bloquee el hilo actual hasta que la solicitud finalice. Por lo tanto,

var it_works = false; 

$.ajax({ 
    url: 'some_file.php', 
    async: false, # makes request synchronous 
    success: function() { 
    it_works = true; 
    } 
}); 

alert(it_works); 
Cuestiones relacionadas