【问题标题】:setInterval in jQuery happens too fastjQuery 中的 setInterval 发生得太快了
【发布时间】:2011-08-06 15:26:38
【问题描述】:

我使用 setInterval,但有时它发生“太快”。如下所示:

setInterval(function() {
    //here comes ajax functions and so on. 
}, 1000);   

有时 setInterval 的发生速度比所有这些 ajax 函数都快,它给了我两条消息而不是一条。有什么办法解决这个问题?

【问题讨论】:

  • 也许你根本不应该使用 setInterval。您可能希望触发这些呼叫,然后在呼叫返回后使用 setTimeout 再次安排呼叫。

标签: javascript jquery setinterval


【解决方案1】:

遇到了这个问题,而 clearInterval 不起作用。

确保 setInterval 只被调用一次,方法是将其包装在 if 语句中:

var interval;

if (typeof(interval) === 'undefined') {
  interval = setInterval(actFakeData,3000);
}

对我也有帮助的是将 setInterval 分配给一个变量并 console.log 它,这样您就可以在整个代码中看到该值。对我来说,当它加速时,它的数值增加而不是重置,直到我把它包裹起来。

【讨论】:

    【解决方案2】:

    我认为这里的问题是由于范围。即使方法触发成功。

    有类似的问题,我可以用这个来解决:

    setTimeout(function(){
        load1();
    }, 5000); 
    
    function load1 () {
        console.log('loaddd1..');
        setTimeout(load2(), 4000); 
    }
    
    function load2 () {
        setTimeout(function(){
        console.log('end load2');
    }, 4000); 
    

    【讨论】:

      【解决方案3】:

      很难说你遇到了什么,问题有点不清楚。

      setInterval 非常适合某些事情,但不适用于您将要混合其他异步内容的任何事情。相反,使用“重新安排setTimeout”成语:

      setTimeout(doSomething, 1000);
      function doSomething() {
          $.ajax("your_url", {
              success: function() {
                  // Do something here
      
                  // Do something else here
              },
              complete: function() {
                  // Previous run complete, schedule the next run
                  setTimeout(doSomething, 1000);
              }
          });
      }
      

      ...因为毕竟,您的ajax 呼叫可能需要一秒钟以上才能完成。

      如果这不是你遇到的问题,我猜你的代码看起来像这样:

      setInterval(function() {
          $.ajax("your_url", {
              success: function() {
                  // Do something here
              }
          });
      
          // Do something else here
      }, 1000);
      

      ...您想知道为什么“在此处执行其他操作”代码在“在此处执行操作”代码之前运行。如果是这样,原因是默认情况下,ajax 调用是异步。您对$.ajax 的呼叫开始,仅此而已;然后所有其他代码在成功(或错误)回调发生之前运行。

      当然,解决方法是在依赖成功回调的顶层不做任何事情

      setInterval(function() {
          $.ajax("your_url", {
              success: function() {
                  // Do something here
      
                  // Do something else here
              }
          });
      
      }, 1000);
      

      【讨论】:

        【解决方案4】:

        最好不要使用setInterval,而是每次设置一个新的setTimeout。例如:

        setTimeout(function ajaxStuff() {
            // here comes ajax functions and so on.
        
            setTimeout(ajaxStuff, 1000);
        }, 1000);
        

        当然,如果其中的函数是异步的,就像 AJAX 请求通常那样,setTimeout 调用仍然会来得太快。当请求完成时,您需要编写一些调用setTimeout 的代码。 $.when 可以帮助您解决这个问题,因为 $.ajax 和其他 jQuery AJAX 方法实现了 $.Deferred

        setTimeout(function ajaxStuff() {
            $.when(
                $.ajax({
                    url: 'ajax1.htm'
                }),
                $.ajax({
                    url: 'ajax2.htm'
                }),
                $.ajax({
                    url: 'ajax3.htm'
                })
            ).done(function() {
                setTimeout(ajaxStuff, 1000);
            });
        }, 1000);
        

        【讨论】:

        • 这不是将 XHR 请求排队,然后立即设置下一个超时,这可能会导致相同的行为吗?
        • @Jason 是的,它会的。我正在编辑中途处理这个问题。
        【解决方案5】:

        设置一个标志,指示 ajax 提取正在进行中。当所有 ajax 获取完成时,清除标志。在 setInterval 函数的顶部,如果设置了标志,则立即返回。

        【讨论】:

          【解决方案6】:

          在 jQuery 1.5.x 中,您可以将 Then() 用于延迟对象。这是一个很好的说法,一旦你完成 then() 就这样做。您还可以使用 When() 选项让它等待多个 ajax 请求完成。

          这两件事很酷很强大。

          http://api.jquery.com/deferred.then/

          http://api.jquery.com/jQuery.when/

          【讨论】:

            猜你喜欢
            • 2022-01-12
            • 2014-02-01
            • 1970-01-01
            • 1970-01-01
            • 2012-05-17
            • 2011-10-07
            • 2016-11-08
            • 1970-01-01
            • 2016-03-21
            相关资源
            最近更新 更多