从jQuery执行同步Ajax请求?

时间:2013-09-11 13:33:13

标签: javascript jquery ajax

我知道这听起来像以前被问过的东西,但是对于我所有的狩猎,我都找不到与我正在寻找的东西相匹配的东西。

我正在开发一个基于Ajax的项目。我正在使用jQuery,但即使使用精美的简化代码,当我已经达到代码完全相同时,它仍然很混乱,除了通过data字段传递的单个命令。 / p>

所以我尝试在处理程序函数中进行设置,如下所示:

function _call(task, opts, async) {
    if(typeof async !== "boolean") { async = true; }
    opts = $.extend({}, opts, options);
    $.ajax({
        url: "myphpfile.php",
        dataType:"JSON",
        type:"POST",
        async:async,
        data: { task: task, opts: opts }
    }).done(function(data) { return data; });
}
  

对于那些通读的人,你会注意到有一个var,   options ,尚未在示例中定义。它实际上   已被分配,为了清楚起见,它被省略了。

我开始意识到这不起作用,因为即使设置为async: false,代码仍会在调用_call(...)后继续,因此无法及时获得结果。我尝试了一些不同的变体,包括将匿名函数传递给处理程序,然后将其用作.done()函数,但它不会与外部变量交互,从而无法实现目的。

我正在寻找的是一个允许我使用它的系统:

var returnedData = _call("thisismytask");
var returnedDataWithOptions = _call("thisisanothertask", {'option': 'option1'});

我真的希望这是可能的。我确信它会是,因为函数的主要目的是消除不必要的重复代码的需要。

感谢。 :)

5 个答案:

答案 0 :(得分:5)

你可以这样做:

function _call(task, opts) {
    opts = $.extend({}, opts, options);
    return $.ajax({
        url: "myphpfile.php",
        dataType:"JSON",
        type:"POST",
        data: { task: task, opts: opts }
    });
}

它不需要将回调传递给_call,但功能却相同。

_call("thisisanothertask", {'option': 'option1'}).then(function(data) {
  // function body here
});

答案 1 :(得分:1)

你最好这样做

function _call(task, opts, callback) {
    opts = $.extend({}, opts, options);

    $.ajax({
        url: "myphpfile.php",
        dataType:"JSON",
        type:"POST",
        data: { task: task, opts: opts }
    }).done(function(data) { callback(data); });
}

像这样使用

_call("thisisanothertask", {'option': 'option1'}, function(data) {
   //do things with data
});

你真的不能这样做,因为_call不能马上回来,因为它可能需要一段时间才能得到回复,即使你可以锁定你的浏览器也不好。

var returnedData = _call("thisismytask");
var returnedDataWithOptions = _call("thisisanothertask", {'option': 'option1'});

你需要像这样使用它:

_call("thisismytask", null, function(returnedData) {
   //use returnData
});

_call("thisisanothertask", {'option': 'option1'}, function(returnedDataWithOptions) {
  //use returnedDataWithOptions
});

如果你需要在这个任务之前得到thisismytask的结果,你将不得不这样做:

_call("thisismytask", null, function(returnedData) {

   _call("thisisanothertask", {'option': 'option1'}, function(returnedDataWithOptions) {
     //use returnData

     //use returnedDataWithOptions
   });

});

答案 2 :(得分:1)

你应该使用回调。您也不应该使用async: false,因为这将阻止浏览器中的UI线程。您可以使用jQuery.when()同步各种任务。首先改变你的方法:

function _call(task, opts) {
    opts = $.extend({}, opts, options);
    return $.ajax({
        url: "myphpfile.php",
        dataType:"JSON",
        type:"POST",
        data: { task: task, opts: opts }
    });
}

现在你可以这样称呼它:

$.when(
    _call("thisismytask"),
    _call("thisisanothertask", {'option': 'option1'})
).done(function(firstCallResults, secondCallResults) {
    //*CallResults is an array with the following structure: [data, statusText, jqXHR]
    var returnedData = firstCallResults[0];
    var returnedDataWithOptions = secondCallResults[0];
    ...
});

通过这种方式,您可以保持AJAX异步性的所有好处(这些任务将并行运行,除非服务器不支持它)并在结果全部可用时将结果重新组合在一起。

答案 3 :(得分:0)

我找到了解决方案。 @Slavo向我指出。

  

https://stackoverflow.com/a/6685294/563460
  在进行同步请求时,应该是

function getRemote() {
     return $.ajax({
         type: "GET",
         url: remote_url,
         async: false,
     }).responseText; }
  

示例 - http://api.jquery.com/jQuery.ajax/#example-3

现在我只需要从文本解码到正确的JSON。谢谢大家。 :)

答案 4 :(得分:0)

使用jQuery的语法 -    它为我工作,

$.ajaxSetup({async: false});