JavaScript: variables globales después de las solicitudes de Ajax [duplicado]

60

la pregunta es bastante simple y técnica:

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 hacerlo? Si no, ¿se puede $.post()devolver un valor al que se aplicará it_works?

1
103

Lo que espera es la solicitud de tipo síncrono ( bloqueo ).

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 asincrónicas ( sin bloqueo ) de forma predeterminada, lo que significa que el navegador no esperará a que se completen para continuar su trabajo. Es por eso que su alerta obtuvo un resultado incorrecto.

Ahora, con jQuery.ajaxpuede configurar opcionalmente la solicitud para que sea síncrona , lo que significa que la secuencia de comandos solo continuará ejecutándose después de que finalice la solicitud.


El RECOMENDADAS manera, sin embargo, es a refactorizar su código para que los datos se transmiten a una devolución de llamada función tan pronto como la petición está terminado. Esto se prefiere porque bloquear la ejecución significa bloquear la interfaz de usuario, lo cual es inaceptable. Hacerlo de esta forma:

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

Asynchronous programming is slightly more complicated because the consequence of making a request is encapsulated in a function instead of following the request statement. But the realtime behavior that the user experiences can be significantly better because they will not see a sluggish server or sluggish network cause the browser to act as though it had crashed. Synchronous programming is disrespectful and should not be employed in applications which are used by people.

Douglas Crockford ( Blog de YUI )

8
  • 4
    Pero tenga en cuenta que esto acabará con la usabilidad si realiza some_file.phpmuchas operaciones (costosas). 11/07/10 a las 8:36
  • 1
    @Felix Sí, pero hay casos en los que la E / S síncrona es esencial. Es una herramienta que no debe usarse en exceso. Es mejor evitarlo, se podría decir.
    gblazex
    11/07/10 a las 8:55
  • y tenga en cuenta que la pregunta eraalert has to be here not inside. Is there a way to do that?
    gblazex
    11/07/10 a las 9:45
  • 2
    @galambalazs: Las solicitudes síncronas quedaron obsoletas. El conocimiento estándar dice que usarlas arrojará un error. 11/10/2014 a las 9:43
  • 1
    Mensaje de la consola de Chrome: "XMLHttpRequest síncrono en el hilo principal está obsoleto debido a sus efectos perjudiciales para la experiencia del usuario final".
    Stefan
    14/07/2016 a las 10:46
6

AJAX son las siglas de Asynchronous JavaScript and XML. Por lo tanto, la publicación en el servidor no está sincronizada con el resto de la función. En su lugar, pruebe un código como este (solo divide la taquigrafía $.posten la $.ajaxllamada más larga y agrega la asyncopción).

var it_works = false;

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

alert(it_works);

¡Espero que esto ayude!

5

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 indicarle cuándo ha finalizado la publicación. No puede realizar la alerta en un alcance global como este y esperar que la publicación ya haya finalizado. Tienes que moverlo a la función de devolución de llamada.

3

La razón por la que su código falla es porque post()iniciará una solicitud asincrónica al servidor. Lo que eso significa para usted es que post()regresa inmediatamente, no después de que se completa la solicitud, como esperaba.

Lo que necesita, entonces, es que la solicitud sea sincrónica y bloquee el hilo actual hasta que se complete la solicitud. 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);