【问题标题】:Do JQuery.ajax call immediately, but not call callbacks until document.ready?JQuery.ajax 是否立即调用,但直到 document.ready 才调用回调?
【发布时间】:2013-12-12 09:43:31
【问题描述】:

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

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() 回调也是如此)。所以我不希望在$(document).ready() 运行之前调用onReply。 jQuery 有什么内置的东西可以让我保证会是这样吗?

附:使用 jQuery 1.10.x

【问题讨论】:

  • 非常相似的问题(一旦你认为使用延迟):stackoverflow.com/questions/6177187/…(但没有一个答案考虑如果 ajax 调用失败会发生什么;他们也不会在页面之前启动 ajax 调用已满载,我想立即启动它。)

标签: jquery ajax jquery-deferred deferred


【解决方案1】:

试试这个:

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.readyState,而不是使用变量来跟踪document的加载状态。

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

【讨论】:

  • @Ramesh:你的怀疑是绝对正确的。看到我已经更新了答案。
  • 此代码是否包含竞争条件,或者 JavaScript 方法是否从未中断/抢占?
  • @Zack 根据我对竞争条件的理解,这不是一个。因为主要事件仅在两个所需事件都发生后才会发生。而且我认为 javascript 方法永远不会被中断。
【解决方案2】:

我最近阅读了Learning jQuery Deferreds,我相信这是我在几个月前发布这个问题时一直在寻找的优雅解决方案!

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

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

这是该解决方案的初稿:

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

【讨论】:

    猜你喜欢
    • 2015-05-12
    • 1970-01-01
    • 2013-11-17
    • 1970-01-01
    • 1970-01-01
    • 2011-04-30
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多