3

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

我正在开发一个非常依赖 Ajax 的项目。我正在使用 jQuery,但即使它的代码流线型优美,但当我得到它的代码完全相同时,它仍然很混乱,除了一个单一的命令通过该data字段。

所以我尝试在处理函数中设置它,如下所示:

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

对于那些仔细阅读的人,您会注意到 options示例中没有定义的 var, 。它实际上已被分配,只是为了清楚起见被省略了。

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

我正在寻找的只是一个可以让我使用它的系统:

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

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

谢谢。:)

4

5 回答 5

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
});
于 2013-09-11T13:44:03.190 回答
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
});

如果您在 thisisanothertask 之前需要 thisismytask 的结果,则必须执行以下操作:

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

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

     //use returnedDataWithOptions
   });

});
于 2013-09-11T13:40:18.263 回答
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 异步特性的所有好处(除非服务器不支持,否则这些任务将并行运行)并在它们全部可用时将结果重新组合在一起。

于 2013-09-11T13:57:24.947 回答
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。谢谢大家。:)

于 2013-09-11T13:57:48.957 回答
0

使用 jQuery 的语法——它对我有用,

$.ajaxSetup({async: false});
于 2015-10-13T08:21:40.383 回答