112

Is it possible to set async: false when calling $.getJSON() so that the call blocks rather than being asynchronous?

Jacob Marble
  • 28,555
  • 22
  • 67
  • 78
ACP
  • 34,682
  • 100
  • 231
  • 371
  • 1
    Just put your code in the callback.... There is a reason this is deprecated - it is a bad idea – Milney Mar 08 '17 at 15:41
  • 1
    @Milney — Very strange… Officially, it _is_ deprecated; actually, it is _not_. If it were really deprecated, the possibility to make either a sync AJAX call or a $ajax.setup switch would have been dropped in jQuery 3. As a matter of fact, a sync call is occasionally very useful, for instance upon initializing globals with JSON data, when you have other globals that rely on the first batch. (Packing the whole initialization process in the callback function could be very tricky under certain circumstances.) – Brice Coustillas Oct 01 '17 at 07:15
  • I think [*Synchronous XHR requests or Restructure code*](https://stackoverflow.com/a/1739812/4058484) would answer this case. – eQ19 Jun 02 '18 at 22:59

7 Answers7

161

You need to make the call using $.ajax() to it synchronously, like this:

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

This would match currently using $.getJSON() like this:

$.getJSON(myUrl, myData, function(data) { 
  //stuff
  //...
});
sbmsr
  • 133
  • 1
  • 10
Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • 26
    I have found the convenience method $.getJSON() to almost never be useful, and always end up using $.ajax(). – Jacob Marble Oct 08 '12 at 06:27
  • 1
    can I use this for POST call as well? – Hitesh Apr 19 '14 at 07:55
  • @hitesh yes, you'd add a `type: 'POST'` option to as well to turn it into a post - though you don't want to use `async: false` unless you *really* need to - it'll lock up the UI. – Nick Craver Apr 19 '14 at 12:24
  • 1
    What is the 'myData' supposed to be in this case? When I delete data: myData completely it does work.. Fairly new to ajax calls! – nclsvh Aug 05 '15 at 15:38
  • 2
    Just bumped into the following new problem: "Synchronous XMLHttpRequest outside of workers is in the process of being removed from the web platform as it has detrimental effects to the end user's experience. (This is a long process that takes many years.) Developers must not pass false for the async argument when entry settings object's global object is a Window object. User agents are strongly encouraged to warn about such usage in developer tools and may experiment with throwing an InvalidAccessError exception when it occurs." – Ken Sharp Dec 29 '15 at 16:19
  • Ajax async default value is "True", So getJSON async value is "True". if you want to use your ajax call in "Promise Mode" you need to use ajax not getJSON and set async to false. – Xaimaran Apr 23 '16 at 14:07
47

Both answers are wrong. You can. You need to call

$.ajaxSetup({
async: false
});

before your json ajax call. And you can set it to true after call retuns ( if there are other usages of ajax on page if you want them async )

Jay D
  • 3,263
  • 4
  • 32
  • 48
velja
  • 601
  • 5
  • 2
  • 1
    I just reread that part of docs. Here is the part that talks about ajaxSetup: http://api.jquery.com/jQuery.ajaxSetup/ And here are options: http://api.jquery.com/jQuery.ajax/ It clearly says: "async Default: true By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. " JSONP is not JSON so I still think I am right from the beginning. I will write example later when I get some time. – velja Sep 26 '11 at 14:12
  • 7
    This is a late comment but... which are the "both" answers that are wrong? I see the answer from @Nick Craver to be both acceptable and not "mess" with the global AJAX settings (should other requests be firing at the same time) – scunliffe May 22 '13 at 20:12
  • 1
    It works, but this would apply that to all the ajax requests that you make in the page. So im gonna downvote as i would not recommend it – GabrielBB Aug 25 '14 at 15:03
  • 4
    This is a very low quality answer – Brian Webster Jan 10 '15 at 18:01
  • 1
    -1: Making things synchronous can be costly. You should most definitely be doing this on a per-call basis unless your project absolutely requires it every time. Your answer suggests that you globally configure all calls to `$.ajax` (and subsequent shorthand wrappers ie `$.getJSON`, `$.get`, etc.) to be synchronous. Furthermore, the [documentation](http://api.jquery.com/jQuery.ajaxSetup/) even suggests not using this: "Description: Set default values for future Ajax requests. Its use is not recommended." – Carrie Kendall Apr 07 '15 at 19:26
  • I want to add to negative comments that you can't know that another async ajax call will be not called before you set again `async = true`. – Marco Sulla Feb 14 '23 at 09:52
19

I think you both are right. The later answer works fine but its like setting a global option so you have to do the following:

    $.ajaxSetup({
        async: false
    });

    //ajax call here

    $.ajaxSetup({
        async: true
    });
webdev
  • 598
  • 5
  • 16
11

In my case, Jay D is right. I have to add this before the call.

$.ajaxSetup({
    async: false
});

In my previous code, I have this:

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

It works find. Then I change to

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

The alert is undefined.

If I add those three lines, the alert shows the data again.

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

If you just need to await to avoid nesting code:

let json;
await new Promise(done => $.getJSON('https://***', async function (data) {
    json = data;
    done();
}));
k06a
  • 17,755
  • 10
  • 70
  • 110
0

I don't think you can set that option there. You will have to use jQuery.ajax() with the appropriate parameters (basically getJSON just wraps that call into an easier API, as well).

Daff
  • 43,734
  • 9
  • 106
  • 120
0

Roll your own e.g.

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