Czy można ustawić async: false na wywołanie $ .getJSON

105

Czy można ustawić async: falsepodczas wywoływania $.getJSON()tak, aby wywołanie blokowało się, a nie było asynchroniczne?

ACP
źródło
1
Po prostu umieść swój kod w wywołaniu zwrotnym .... Jest powód, dla którego to jest przestarzałe - to zły pomysł
Milney
1
@Milney - Bardzo dziwne… Oficjalnie jest to przestarzałe; w rzeczywistości tak nie jest . Gdyby był naprawdę przestarzały, możliwość wykonania wywołania synchronizacji AJAX lub przełącznika $ ajax.setup zostałaby odrzucona w jQuery 3. W rzeczywistości wywołanie synchronizacji jest czasami bardzo przydatne, na przykład podczas inicjowania globalnych Dane JSON, gdy masz inne globalne, które opierają się na pierwszej partii. (Pakowanie całego procesu inicjalizacji w funkcji wywołania zwrotnego może w pewnych okolicznościach być bardzo trudne.)
Brice Coustillas
Myślę, że synchroniczne żądania XHR lub kod Restrukturyzacja byłyby odpowiedzią na ten przypadek.
Chetabahana

Odpowiedzi:

154

Musisz nawiązać połączenie, używając $.ajax()do niego synchronicznie, na przykład:

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

Pasowałoby to obecnie przy użyciu $.getJSON()takiego:

$.getJSON(myUrl, myData, function(data) { 
  //stuff
  //...
});
Nick Craver
źródło
23
Przekonałem się, że wygodna metoda $ .getJSON () prawie nigdy nie jest użyteczna i zawsze kończy się na użyciu $ .ajax ().
Jacob Marble
czy mogę tego użyć również do wywołania POST?
Hitesh
@hitesh tak, możesz również dodać type: 'POST'opcję, aby przekształcić go w post - chociaż nie chcesz go używać, async: falsechyba że naprawdę musisz - spowoduje to zablokowanie interfejsu użytkownika.
Nick Craver
1
Jak w tym przypadku powinny być „myData”? Kiedy usuwam dane: myData całkowicie działa .. Dość nowość w wywołaniach Ajax!
nclsvh
2
Właśnie natknąłem się na następujący nowy problem: „Synchroniczny XMLHttpRequest poza pracownikami jest w trakcie usuwania z platformy internetowej, ponieważ ma to szkodliwy wpływ na doświadczenie użytkownika końcowego. (Jest to długi proces, który zajmuje wiele lat). Programiści muszą nie przekazuj false dla argumentu async, gdy globalnym obiektem obiektu ustawień wpisu jest obiekt Window. Zaleca się, aby agenty użytkownika ostrzegały o takim użyciu w narzędziach programistycznych i mogą eksperymentować z wyrzucaniem wyjątku InvalidAccessError, gdy wystąpi. "
Ken Sharp
46

Obie odpowiedzi są błędne. Możesz. Musisz zadzwonić

$.ajaxSetup({
async: false
});

przed wywołaniem json ajax. I możesz ustawić to na true po ponownym wywołaniu połączenia (jeśli są inne zastosowania Ajax na stronie, jeśli chcesz, aby były asynchroniczne)

velja
źródło
1
Właśnie ponownie przeczytałem tę część dokumentów. Oto część, która mówi o ajaxSetup: api.jquery.com/jQuery.ajaxSetup A oto opcje: api.jquery.com/jQuery.ajax Wyraźnie mówi: "async Default: true Domyślnie wszystkie żądania są wysyłane asynchronicznie ( czyli domyślnie jest ustawiona na „prawda”). Jeśli potrzebujesz żądań synchronicznych, ustaw tę opcję na „fałsz”. Żądania międzydomenowe i żądania dataType: „jsonp” nie obsługują operacji synchronicznych. „JSONP to nie JSON, więc nadal myślę, że tak od samego początku. Napiszę przykład później, kiedy będę miał trochę czasu.
velja
7
To późny komentarz, ale ... które odpowiedzi „obu” są błędne? Widzę, że odpowiedź od @Nick Craver jest zarówno akceptowalna, jak i nie „bałagan” z globalnymi ustawieniami AJAX (jeśli inne żądania będą odpalane w tym samym czasie)
scunliffe
1
Działa, ale dotyczyłoby to wszystkich żądań ajax, które tworzysz na stronie. Więc zamierzam głosować w dół, ponieważ nie polecam tego
GabrielBB,
3
To jest bardzo niskiej jakości odpowiedź
Brian Webster
1
-1: Synchronizacja rzeczy może być kosztowna. Z całą pewnością powinieneś to robić na zasadzie pojedynczego połączenia, chyba że twój projekt absolutnie wymaga tego za każdym razem. Twoja odpowiedź sugeruje, że globalnie skonfigurować wszystkie połączenia $.ajax(z późniejszymi owijarki skrócone tj $.getJSON, $.getitp) jest synchroniczny. Ponadto dokumentacja sugeruje nawet, aby nie używać tego: „Opis: Ustaw wartości domyślne dla przyszłych żądań Ajax. Nie zaleca się jego używania”.
Carrie Kendall
18

Myślę, że oboje macie rację. Późniejsza odpowiedź działa dobrze, ale przypomina ustawienie opcji globalnej, więc musisz wykonać następujące czynności:

    $.ajaxSetup({
        async: false
    });

    //ajax call here

    $.ajaxSetup({
        async: true
    });
webdev
źródło
10

W moim przypadku Jay D ma rację. Muszę to dodać przed rozmową.

$.ajaxSetup({
    async: false
});

W moim poprzednim kodzie mam to:

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));

To działa znaleźć. Potem zmieniam na

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

Alert jest niezdefiniowany.

Jeśli dodam te trzy linie, alert ponownie pokaże dane.

$.ajaxSetup({
    async: false
});
var jsonData= (function() {
    var result;
    $.getJSON('data.txt', {}, function(data){
      result = data;
    });
    return result;
})();
alert(JSON.stringify(jsonData));
ronrun
źródło
1

Jeśli chcesz tylko awaituniknąć zagnieżdżania kodu:

let json;
await new Promise(done => $.getJSON('https://***', async function (data) {
    json = data;
    done();
}));
k06a
źródło
0

Myślę, że nie można tam ustawić tej opcji. Będziesz musiał użyć jQuery.ajax () z odpowiednimi parametrami (w zasadzie getJSON po prostu opakowuje to wywołanie w łatwiejsze API).

Daff
źródło
0

Zroluj własny np

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
źródło