【问题标题】:How do I stop a window.setInterval in javascript?如何在 javascript 中停止 window.setInterval?
【发布时间】:2011-09-02 05:30:56
【问题描述】:

我有一个每 2000 毫秒调用一次的 javascript 函数。我想停止这种情况,这样我就可以让用户在页面上执行其他操作,而无需再次调用它。这可能吗?这是每 2000 毫秒调用一次的函数:

window.setInterval(function getScreen (sid) {
        if (window.XMLHttpRequest)
        {// code for IE7+, Firefox, Chrome, Opera, Safari
          xmlhttp=new XMLHttpRequest();
        }
        else
        {// code for IE6, IE5
          xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
        }
        xmlhttp.onreadystatechange=function()
        {
        if (xmlhttp.readyState==4 && xmlhttp.status==200)
          {
            document.getElementById("refresh").innerHTML=xmlhttp.responseText;
          }
        }
        xmlhttp.open("POST","getScreen.php?sid="+<?php echo $sid; ?>,true);
        xmlhttp.send();
    },2000);

【问题讨论】:

  • 这是一个 DoS 漏洞。如果您的 XMLHttpRequest 花费的时间超过 2 秒(由于流量/负载)怎么办?您将堆积请求并冒着关闭服务器的风险。考虑阅读this 文章并使用超时(或)适当的调度。

标签: javascript jquery


【解决方案1】:

没有内置的“暂停”功能,但您可以停止它,然后使用相同的功能开始新的间隔。

首先需要捕获调用setInterval返回的id:

let intervalId = window.setInterval(...);

然后当你想停止它时,调用

 window.clearInterval(intervalId);

在您的情况下,我建议单独定义setScreen,而不是在对setInterval 的调用中。这样,当你想恢复它时,你可以使用intervalId = window.setInterval(setScreen, 2000)

【讨论】:

    【解决方案2】:

    如果您使用 jQuery,我会推荐插件 jQuery Timer

    var timer = $.timer(function() {
      alert('This message was sent by a timer.');
    }, 2000, true);
    

    然后你可以轻松地暂停计时器:

    timer.pause();
    

    也恢复它:

    timer.play();
    

    【讨论】:

    • 感谢您的提示,它很有用。
    【解决方案3】:

    使用window.setTimeout() 而不是window.setInterval() 更容易做到这一点。以下内容改编自我的回答here

    现场演示:http://jsfiddle.net/timdown/Hkzex/

    代码:

    function RecurringTimer(callback, delay) {
        var timerId, start, remaining = delay;
    
        this.pause = function() {
            window.clearTimeout(timerId);
            remaining -= new Date() - start;
        };
    
        var resume = function() {
            start = new Date();
            timerId = window.setTimeout(function() {
                remaining = delay;
                resume();
                callback();
            }, remaining);
        };
    
        this.resume = resume;
    
        this.resume();
    }
    

    【讨论】:

    • 非常好!我设法很容易地从暂停延迟中添加了一个启动。不过,您在 github 上的 Timer 版本似乎更像是操作的完美答案。泰!
    【解决方案4】:

    您不能暂停间隔,但可以停止并重新启动它。

    var timer = setInterval(xx,tt);
    
    // then some time later
    clearInterval(timer);
    

    您只需要从setInterval() 捕获返回值并在您想要停止它时调用clearInterval()

    另一种可以随时停止重复的重复方法是重复setTimeout(),然后clearTimeout() 停止下一个计时器,或者只是不启动下一个setTimeout()

    【讨论】:

      【解决方案5】:

      不要重新声明任何东西

      只需添加一个告诉间隔不要做任何事情的类。例如:悬停时。

      var i = 0;
      window.setInterval(function() { //declare new function
        if(!$('#counter').hasClass('pauseInterval')) { //only run if it hasn't got this class 'pauseInterval'
          $('#showCount').html(i++); //just for explaining and showing
        }
      }, 500);
      
      $('#counter').hover(function() { //mouse enter
          $(this).addClass('pauseInterval');
          $('#counting').text('Stopped counting...');
        },function() { //mouse leave
          $(this).removeClass('pauseInterval');
          $('#counting').text('Counting...');
        }
      );
      <!-- you'll need jQuery for this. If you really want a vanilla version, ask -->
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      
      
      <div id="counter"><span id="counting">Counting...</span> | <span id="showCount"></span></div>

      【讨论】:

        【解决方案6】:

        不要使用setInterval()尤其是在处理网络(XHR/fetch)调用时。无法保证您的请求会按时完成,但setTimeout() 不会等待启动下一个打开越来越多的连接。

        只需使用 setTimeout() 即可,通过简单的 if 语句自行重新安排时间。

        
        function updateContent() {
            someFunctionReturningAPromise()
                .then(() => {
                    if (continue) {
                        setTimeout(updateContent), 2000);
                    }
                })
                .catch(e => console.log(e));
        }
        
        updateContent()
        
        

        【讨论】:

          【解决方案7】:
          var intervalId = window.setInterval(code);
          window.clearInterval(intervalId);
          

          【讨论】:

          • 能否请您 edit 解释为什么这段代码回答了这个问题?不鼓励仅使用代码的答案,因为它们不教授解决方案。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-06-05
          • 1970-01-01
          • 2012-11-19
          • 2014-09-20
          • 2021-07-18
          相关资源
          最近更新 更多