JQuery.ajax立即调用,但是直到document.ready才调用回调函数?

时间:2013-12-12 09:43:31

标签: jquery ajax jquery-deferred deferred

我正在使用jQuery,目前正在$.ajax()函数内进行$(document).ready()调用。但是我意识到要进行AJAX调用我不会使用DOM中的任何内容。此外,Ajax调用可能需要一个或两个(或更多)服务器端。所以,出于这两个原因,我想尽快让它继续下去,而我正在考虑重构我的代码看起来像这样(这将在靠近顶部的<script>块中进行。 HTML文件):

var someGlobal="whatever";
...
function onReply(response){
  //Do something
}
...
$.ajax({
   'url':"call_me.json",
   'type':'POST',
   'data':{x:someGlobal,y:"Dude!"}
  })
  .fail(function(jqXHR,status){
    console.log("AJAX ERROR:" + status);
    })
  .done(onReply);
...

但是,onReply()回调确实需要构建DOM(同样适用于.fail()回调)。所以我不希望在onReply运行之前调用$(document).ready()。有什么内置的jQuery允许我保证将是这种情况吗?

P.S。使用jQuery 1.10.x

2 个答案:

答案 0 :(得分:2)

试试这个:

var flag = 0;
function onReply(response){
    if (flag == 0)
    {
        $(document).ready(
            function () {
                anotherfunction(response);
            });
    }
    else
        anotherfunction(response);
}

$(document).ready(
    function () {
        flag = 1;
    }
);

function anotherfunction(resp) {
    // Do something
}

更好的方式(1。5年后):
我们可以使用javascript自己的document,而不是使用变量来跟踪document.readyState的加载状态。

function onReply(response){
    function ProcessResponse() {
        // Do something with 'response'
    }
    document.readyState == 'complete' ? ProcessResponse() : $(ProcessResponse);
}

答案 1 :(得分:0)

我最近阅读了Learning jQuery Deferreds,我相信这是我想要的优雅解决方案,几个月前,当我发布这个问题时!

要使用它,我创建了一个全局Deferred对象,当DOM准备就绪时,它是resolve()。从Deferred对象中,我提取了一个promise,$.ajax()调用返回一个promise。我不希望onReply()(或ajax错误处理)被调用,直到这些操作完成,或者在延迟行话中,直到两个promise都已解决。我们这样做的方法是使用$.when(),它接受​​一个promises(*)列表等待,并返回另一个promise对象,我们可以附加fail()done()处理程序

*:从技术上讲,它们不需要是承诺对象;它们也可以是正常的功能。

以下是该解决方案的初稿:

var someGlobal = 'whatever';
var readyToInit = $.Deferred();
...
function onReply(response){
  //Do something
}
...
var ajaxPromise = $.ajax({
   'url':'call_me.json',
   'type':'POST',
   'data':{x:someGlobal,y:'Dude!'}
  });

$.when( ajaxPromise, readyToInit.promise() )
  .fail(function(jqXHR,status){
    console.log('AJAX ERROR:' + status);
    })
  .done(onReply);
...
$(function() {  //OnReady
    readyToInit.resolve();  //Anything waiting for the page to load can go now
});