É possível definir async: false para $ .getJSON call


105

É possível definir async: falseao chamar $.getJSON()para que a chamada seja bloqueada em vez de ser assíncrona?


1
Basta colocar seu código no retorno de chamada .... Há um motivo para isso ser descontinuado - é uma má ideia
Milney

1
@Milney - Muito estranho… Oficialmente, está obsoleto; na verdade, é não . Se fosse realmente obsoleto, a possibilidade de fazer uma chamada de sincronização AJAX ou um switch $ ajax.setup teria sido descartada no jQuery 3. Na verdade, uma chamada de sincronização é ocasionalmente muito útil, por exemplo, ao inicializar globais com Dados JSON, quando você tem outros globais que dependem do primeiro lote. (Empacotar todo o processo de inicialização na função de retorno de chamada pode ser muito complicado em certas circunstâncias.)
Brice Coustillas,

Respostas:


154

Você precisa fazer a chamada usando $.ajax()para ele de forma síncrona, assim:

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

Isso corresponderia ao uso atual $.getJSON()desta forma:

$.getJSON(myUrl, myData, function(data) { 
  //stuff
  //...
});

23
Eu descobri que o método de conveniência $ .getJSON () quase nunca é útil e sempre acabo usando $ .ajax ().
Jacob Marble

posso usar isso para chamada POST também?
Hitesh

@hitesh sim, você também adicionaria uma type: 'POST'opção para transformá-lo em um post - embora você não queira usar a async: falsemenos que realmente precise - ele bloqueará a IU.
Nick Craver

1
O que 'myData' deve ser neste caso? Quando eu excluo dados: myData completamente, ele funciona .. Bastante novo para chamadas ajax!
nclsvh

2
Acabei de dar de cara com o seguinte novo problema: "XMLHttpRequest síncrono fora dos trabalhadores está em processo de remoção da plataforma da web, pois tem efeitos prejudiciais para a experiência do usuário final. (Este é um processo longo que leva muitos anos.) Os desenvolvedores devem não passa falso para o argumento async quando o objeto global do objeto de configurações de entrada é um objeto Window. Os agentes do usuário são fortemente encorajados a avisar sobre esse uso em ferramentas de desenvolvedor e podem experimentar lançar uma exceção InvalidAccessError quando ela ocorrer. "
Ken Sharp

46

Ambas as respostas estão erradas. Você pode. Você precisa ligar

$.ajaxSetup({
async: false
});

antes de sua chamada json ajax. E você pode definir como verdadeiro após a retomada da chamada (se houver outros usos de ajax na página, se você quiser que sejam assíncronos)


1
Acabei de reler essa parte da documentação. Aqui está a parte que fala sobre ajaxSetup: api.jquery.com/jQuery.ajaxSetup E aqui estão as opções: api.jquery.com/jQuery.ajax Diz claramente: "async Padrão: true Por padrão, todas as solicitações são enviadas de forma assíncrona ( ou seja, isso é definido como verdadeiro por padrão). Se você precisar de solicitações síncronas, defina esta opção como falsa. Solicitações entre domínios e dataType: solicitações "jsonp" não suportam operação síncrona. "JSONP não é JSON, então ainda acho que sou desde o início. Escreverei um exemplo mais tarde, quando tiver algum tempo.
velja

7
Este é um comentário tardio, mas ... quais são as "duas" respostas que estão erradas? Vejo que a resposta de @Nick Craver é aceitável e não "bagunça" as configurações globais de AJAX (caso outras solicitações sejam disparadas ao mesmo tempo)
scunliffe

1
Funciona, mas isso se aplicaria a todas as solicitações de ajax que você fizer na página. Então, eu vou votar negativamente, pois não recomendo
GabrielBB

3
Esta é uma resposta de qualidade muito baixa
Brian Webster

1
-1: Tornar as coisas síncronas pode ser caro. Definitivamente, você deve fazer isso por chamada, a menos que seu projeto exija absolutamente isso todas as vezes. Sua resposta sugere que você configure globalmente todas as chamadas para $.ajax(e wrappers abreviados subsequentes $.getJSON, ou seja $.get, etc.) para serem síncronas. Além disso, a documentação sugere até mesmo não usar isso: "Descrição: Definir valores padrão para solicitações futuras do Ajax. Seu uso não é recomendado."
Carrie Kendall,

18

Eu acho que vocês dois estão certos. A última resposta funciona bem, mas é como definir uma opção global, então você deve fazer o seguinte:

    $.ajaxSetup({
        async: false
    });

    //ajax call here

    $.ajaxSetup({
        async: true
    });

10

No meu caso, Jay D está certo. Eu tenho que adicionar isso antes da chamada.

$.ajaxSetup({
    async: false
});

Em meu código anterior, eu tenho este:

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. Então eu mudo para

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

O alerta é indefinido.

Se eu adicionar essas três linhas, o alerta mostra os dados novamente.

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

1

Se você só precisa awaitevitar o código de aninhamento:

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

0

Eu não acho que você pode definir essa opção lá. Você terá que usar jQuery.ajax () com os parâmetros apropriados (basicamente getJSON apenas envolve essa chamada em uma API mais fácil, também).


0

Role o seu próprio, por exemplo

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);
})
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.