能否在$.getJSON调用中设置async:false?

112

在调用$.getJSON()时,是否可以设置async: false,以使调用阻塞而不是异步执行?


1
只需将您的代码放入回调函数中即可...这种方法被弃用是有原因的——它是一个坏主意。 - Milney
1
@Milney - 非常奇怪...官方上说它已经被弃用了,但实际上并没有。如果它真的被弃用了,在jQuery 3中就不可能再使用同步AJAX调用或$ajax.setup开关了。事实上,同步调用有时非常有用,例如在使用JSON数据初始化全局变量时,当您有其他依赖于第一批全局变量的全局变量时。(在某些情况下,将整个初始化过程打包到回调函数中可能非常棘手。) - Brice Coustillas
我认为同步XHR请求或重构代码可以解决这个问题。 - eQ19
7个回答

161

你需要使用$.ajax()同步调用它,像这样:

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

使用$.getJSON(),可以进行如下匹配:

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

27
我发现方便的方法$.getJSON()几乎从不有用,总是最终使用$.ajax()。 - Jacob Marble
1
我可以将其用于POST调用吗? - Hitesh
@hitesh 是的,您还需要添加一个 type: 'POST' 选项来将其转换为post - 尽管您不想使用 async: false,除非您真的需要它-它会锁定UI。 - Nick Craver
1
在这种情况下,“myData”应该是什么?当我完全删除数据:myData时,它确实有效。我对ajax调用还比较新! - nclsvh
2
刚刚遇到了一个新问题:“在工作线程之外使用同步XMLHttpRequest正在被逐步从Web平台中移除,因为它对最终用户的体验有负面影响。(这是一个需要多年时间的漫长过程。)当入口设置对象的全局对象是Window对象时,开发人员不得将async参数传递为false。强烈建议用户代理在开发者工具中警告此类用法,并可以尝试在出现此类用法时抛出InvalidAccessError异常。” - Ken Sharp
Ajax异步默认值为“True”,因此getJSON异步值为“True”。如果您想在“Promise Mode”中使用自己的ajax调用,则需要使用ajax而不是getJSON并将async设置为false。 - Xaimaran

47

两个答案都是错误的。 你可以。你需要调用

$.ajaxSetup({
async: false
});

在你的json ajax调用之前设置,如果页面中有其他ajax使用而且你希望它们异步执行,则可以在调用返回后将其设置为true。


1
我刚刚重新阅读了文档的这部分内容。这里是讲解ajaxSetup的部分:http://api.jquery.com/jQuery.ajaxSetup/这里是选项:http://api.jquery.com/jQuery.ajax/它清楚地说明: “async 默认值:true默认情况下,所有请求都是异步发送(即默认情况下设置为true)。如果需要同步请求,请将此选项设置为false。跨域请求和dataType:“jsonp”请求不支持同步操作。 ” JSONP不是JSON,所以我仍然认为从一开始我就是对的。等我有时间时,我会写一个例子。 - velja
7
这是一个晚期的评论,但是...哪些是错误的“两个”答案?我认为@Nick Craver的回答是可以接受的,并且不会“干扰”全局AJAX设置(如果同时有其他请求正在发生)。 - scunliffe
1
它能工作,但这将应用于页面中进行的所有ajax请求。因此,我会投反对票,因为我不建议这样做。 - GabrielBB
4
这是一个非常低质量的回答。 - Brian Webster
1
-1:将事情变成同步的可能会很昂贵。除非您的项目绝对需要每次都这样做,否则应该在每个调用基础上执行此操作。您的答案表明您全局配置了所有对$.ajax(以及随后的简写包装器,即$.getJSON$.get等)的调用都是同步的。此外,文档甚至建议不要使用它:“描述:为未来的Ajax请求设置默认值。不建议使用它。” - Carrie Kendall
我想补充一下负面评论,即在重新设置“async = true”之前,您无法确定另一个异步ajax调用是否会被调用。 - Marco Sulla

19

我认为你们两个都是正确的。后一个答案可以正常工作,但它就像设置全局选项一样,因此您必须执行以下操作:

    $.ajaxSetup({
        async: false
    });

    //ajax call here

    $.ajaxSetup({
        async: true
    });

11

在我个人的情况下,Jay D是正确的。在调用之前我必须添加这个。

$.ajaxSetup({
    async: false
});

在我的先前代码中,我有以下这段代码:

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

它能够正常工作。然后我进行了更改。

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

警告未定义。

如果我添加这三行,警告将再次显示数据。

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

1
如果您只需要使用await来避免嵌套代码:
let json;
await new Promise(done => $.getJSON('https://***', async function (data) {
    json = data;
    done();
}));

0

我认为你不能在那里设置该选项。你需要使用jQuery.ajax()和适当的参数(基本上,getJSON只是将该调用包装成更简单的API)。


0

自己动手,举个例子。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接