¿Es posible establecer async: false en $ .getJSON call

105

¿Es posible configurar async: falseal llamar $.getJSON()para que la llamada se bloquee en lugar de ser asincrónica?

ACP
fuente
1
Simplemente coloque su código en la devolución de llamada ... Hay una razón por la que esto está desaprobado: es una mala idea
Milney
1
@Milney - Muy extraño ... Oficialmente, está desaprobado; En realidad, es no . Si realmente estuviera en desuso, la posibilidad de realizar una llamada de sincronización AJAX o un conmutador $ ajax.setup se habría eliminado en jQuery 3. De hecho, una llamada de sincronización es ocasionalmente muy útil, por ejemplo, al inicializar globales con Datos JSON, cuando tiene otros globales que dependen del primer lote. (Empacar todo el proceso de inicialización en la función de devolución de llamada podría ser muy complicado en determinadas circunstancias).
Brice Coustillas
Creo que las solicitudes XHR sincrónicas o el código de reestructuración responderían a este caso.
Chetabahana

Respuestas:

154

Necesita hacer la llamada usándola $.ajax()sincrónicamente, así:

$.ajax({
  url: myUrl,
  dataType: 'json',
  async: false,
  data: myData,
  success: function(data) {
    //stuff
    //...
  }
});

Esto coincidiría con el uso actual de $.getJSON()esta manera:

$.getJSON(myUrl, myData, function(data) { 
  //stuff
  //...
});
Nick Craver
fuente
23
He descubierto que el método de conveniencia $ .getJSON () casi nunca es útil y siempre termino usando $ .ajax ().
Jacob Marble
¿Puedo usar esto también para la llamada POST?
Hitesh
@hitesh sí, también agregarías una type: 'POST'opción para convertirlo en una publicación, aunque no quieres usarlo a async: falsemenos que realmente lo necesites, bloqueará la interfaz de usuario.
Nick Craver
1
¿Qué se supone que es 'myData' en este caso? Cuando elimino datos: myData por completo, funciona ... ¡Bastante nuevo en llamadas ajax!
nclsvh
2
Me encontré con el siguiente problema nuevo: "XMLHttpRequest sincrónico fuera de los trabajadores está en proceso de ser eliminado de la plataforma web ya que tiene efectos perjudiciales para la experiencia del usuario final. (Este es un proceso largo que toma muchos años). Los desarrolladores deben no pasar falso para el argumento asíncrono cuando el objeto global del objeto de configuración de entrada es un objeto de ventana. Se recomienda encarecidamente a los agentes de usuario que adviertan sobre dicho uso en las herramientas de desarrollo y pueden experimentar lanzando una excepción InvalidAccessError cuando ocurre ".
Ken Sharp
46

Ambas respuestas son incorrectas. Usted puede. Necesitas llamar

$.ajaxSetup({
async: false
});

antes de su llamada json ajax. Y puede configurarlo en verdadero después de la devolución de llamadas (si hay otros usos de ajax en la página si los desea asíncronos)

velja
fuente
1
Acabo de volver a leer esa parte de los documentos. Aquí está la parte que habla sobre ajaxSetup: api.jquery.com/jQuery.ajaxSetup Y aquí hay opciones: api.jquery.com/jQuery.ajax Dice claramente: "async Predeterminado: verdadero Por defecto, todas las solicitudes se envían de forma asincrónica ( es decir, esto está configurado en verdadero de forma predeterminada). Si necesita solicitudes síncronas, configure esta opción en falso. Solicitudes entre dominios y tipo de datos: las solicitudes "jsonp" no admiten la operación síncrona. "JSONP no es JSON, así que todavía creo que lo soy Desde el principio. Escribiré un ejemplo más tarde cuando tenga tiempo.
velja
7
Este es un comentario tardío pero ... ¿cuáles son las respuestas "ambas" incorrectas? Veo que la respuesta de @Nick Craver es aceptable y no "ensucia" con la configuración global de AJAX (en caso de que se
activen
1
Funciona, pero esto se aplicaría a todas las solicitudes ajax que realiza en la página. Así que va a im downvote como yo no lo recomendaría
GabrielBB
3
Esta es una respuesta de muy baja calidad
Brian Webster
1
-1: Hacer las cosas sincrónicas puede ser costoso. Definitivamente debería hacer esto por llamada a menos que su proyecto lo requiera absolutamente todo el tiempo. Su respuesta sugiere que configure globalmente todas las llamadas a $.ajax(y envolturas de taquigrafía subsiguientes $.getJSON, es decir $.get, etc.) para que sean sincrónicas. Además, la documentación incluso sugiere no usar esto: "Descripción: Establecer valores predeterminados para futuras solicitudes de Ajax. No se recomienda su uso".
Carrie Kendall
18

Creo que ambos tienen razón. La respuesta posterior funciona bien, pero es como configurar una opción global, por lo que debe hacer lo siguiente:

    $.ajaxSetup({
        async: false
    });

    //ajax call here

    $.ajaxSetup({
        async: true
    });
webdev
fuente
10

En mi caso, Jay D tiene razón. Tengo que agregar esto antes de la llamada.

$.ajaxSetup({
    async: false
});

En mi código anterior, tengo esto:

var jsonData= (function() {
    var result;
    $.ajax({
        type:'GET',
        url:'data.txt',
        dataType:'json',
        async:false,
        success:function(data){
            result = data;
        }
    });
    return result;
})();
alert(JSON.stringify(jsonData));

Funciona encontrar. Entonces cambio a

var jsonData= (function() {
    var result;
    $.getJSON('data.txt', {}, function(data){
      result = data;
    });
    return result;
})();
alert(JSON.stringify(jsonData));

La alerta no está definida.

Si agrego esas tres líneas, la alerta muestra los datos nuevamente.

$.ajaxSetup({
    async: false
});
var jsonData= (function() {
    var result;
    $.getJSON('data.txt', {}, function(data){
      result = data;
    });
    return result;
})();
alert(JSON.stringify(jsonData));
ronrun
fuente
1

Si solo necesita awaitevitar el código anidado:

let json;
await new Promise(done => $.getJSON('https://***', async function (data) {
    json = data;
    done();
}));
k06a
fuente
0

No creo que puedas establecer esa opción allí. Tendrá que usar jQuery.ajax () con los parámetros apropiados (básicamente getJSON simplemente envuelve esa llamada en una API más fácil, también).

Narciso
fuente
0

Ruede su propio eg

function syncJSON(i_url, callback) {
  $.ajax({
    type: "POST",
    async: false,
    url: i_url,
    contentType: "application/json",
    dataType: "json",
    success: function (msg) { callback(msg) },
    error: function (msg) { alert('error : ' + msg.d); }
  });
}

syncJSON("/pathToYourResouce", function (msg) {
   console.log(msg);
})
Stonedecroze
fuente