【问题标题】:Detecting When Javascript is Done Executing检测 Javascript 何时执行完毕
【发布时间】:2011-10-31 18:24:25
【问题描述】:

在 javascript 中是否有一个事件,我可以绑定某种监听器来告诉我所有 javascript/jQuery/Ajax 何时在页面上执行完毕?在执行开始和我需要侦听器“侦听”的时间之间,页面不会加载/卸载/重新加载等,因此这些事件不起作用。该页面实际上没有做任何事情。单击该按钮并触发一些包含对 Web 服务的 Ajax 调用的 javascript 函数。毕竟都完成了,我想改变window.location。但是在我的情况下,window.location 在网络服务完成之前就发生了变化。

目前使用 setTimeout 来实现这一点,但有时代码需要比正常运行更多的时间,有时 window.location 会在所有其他 javascript 完成之前触发。简单地说

<input type = "button"... onclick="doThis();";

function doThis() {
   try{
      //Contains AJAX calls to web services which is mainly what screws up my timing since it may still be trying to execute stuff when the redirect statement happens
      }
   catch (e) {
      }
  //Currently doing setTimeout(redirect, 10000);
  //Would like to simply detect when all of the above is done and then redirect.  
}

编辑:遗漏了重要信息。 AJAX 调用在 for 循环中。变量和成功回调的使用对我来说并没有那么好,因为当我的成功回调执行时,我的变量在 for 循环中采用了新值。

【问题讨论】:

  • 回调是你的朋友;)

标签: javascript ajax


【解决方案1】:

您要解决的是一个经典的并发编程问题。它通过使用barrier 来解决。

简单来说,你需要:

  1. 数一数你打了多少电话。
  2. 为所有 AJAX 完成事件设置回调。
  3. 使该回调减少调用次数。
  4. 回调检查调用次数是否达到零。如果是,则调用您的最终代码(此处为 redirect)。

实际的实现留给读者作为练习:)

提示:将 AJAX 调用嵌入到处理所有计数器递增和回调设置的函数中。

【讨论】:

  • 所以如果我理解你的话,我会使用一个变量来检测我对 ajax 的最后一次调用确实是我对 ajax 的最后一次调用,然后将我的重定向设置为在该 ajax 调用的成功部分发生?
  • 几乎:您使用该变量来检测不是最后一次调用是最后一次调用,而是最后一次 completion 是最后一次完成。不同之处在于您无法知道您的最后一次通话是否会最后完成,而这种情况发生了很大变化。然后,实际上,您将重定向设置为在所有呼叫都具有completed 时发生。另请注意,您不应使用“成功部分”,而应使用 complete 回调,以避免在其中一个调用失败时阻塞。当然,除非这是预期的行为。
  • 哦。我懂了。我是 100% 自学成才的,所以我对这一切还不是很好。我将研究使用 ajax 完成事件并回复您。非常感谢!
  • ajaxComplete 很棒。但是 ajaxStop 会检测所有 AJAX 何时完成,所以我什至不必担心检测它是否是我最后一次完成。 $("#button").ajaxStop(redirect).
  • 好的,你能在问题标题和标签中指定“jQuery”吗?并记住在您的其他问题中指定它:)
【解决方案2】:

我做什么:

  • 创建一个表示未完成 AJAX 调用数量的变量。
  • 在进行 AJAX 调用之前,增加变量。
  • 在完成 AJAX 调用的代码末尾,调用一个函数(例如 ajaxComplete)。
  • ajaxComplete 应该减少计数。当它达到零时,您就知道您的所有调用都已完成。

【讨论】:

    【解决方案3】:

    假设您使用的是jQuery.ajax,听起来您正在寻找ajaxStop

    【讨论】:

    • 这很好用!!!我唯一不确定的是,如果在处理 ajax 请求期间出现某种错误,我该如何“解除绑定”ajaxStop 请求?即使我的错误回调之一返回,那是否仍然构成 ajaxStop 并且事件仍然会触发?
    • @user877442 - $("#wtv").unbind("ajaxStop");... 我想。
    【解决方案4】:

    您为什么不尝试在回调中使用类似Underscore libraryafter 函数?

    var done = _.after(3, function() {
        window.location = 'http://example.com';
    });
    
    $.ajax({
      url: '/tic',
      success: function() {
        done();
      }
    });
    $.ajax({
      url: '/tac',
      success: function() {
        done();
      }
    });
    $.ajax({
      url: '/toe',
      success: function( data ) {
        done();
      }
    });
    

    【讨论】:

      【解决方案5】:

      您应该检查来自 AJAX 调用的响应,并且仅在该响应中进行重定向。这样您就可以避免在 AJAX 仍在执行时进行重定向。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-04
        • 1970-01-01
        • 1970-01-01
        • 2013-03-12
        • 1970-01-01
        • 2011-12-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多