【问题标题】:How to make a setInterval stop after some time or after a number of actions?如何让 setInterval 在一段时间后或多次操作后停止?
【发布时间】:2012-02-26 12:28:59
【问题描述】:

我用 jQuery 创建了一个“换词”循环 通过使用此答案中的代码: jQuery: Find word and change every few seconds

如何在一段时间后停止它?说是在 60 秒之后还是在它完成循环之后?

(function() {

  // List your words here:
  var words = [
      'Lärare',
      'Rektor',
      'Studievägledare',
      'Lärare',
      'Skolsyster',
      'Lärare',
      'Skolpsykolog',
      'Administratör'
    ],
    i = 0;

  setInterval(function() {
    $('#dennaText').fadeOut(function() {
      $(this).html(words[i = (i + 1) % words.length]).fadeIn();
    });
    // 2 seconds
  }, 2000);

})();

【问题讨论】:

    标签: javascript loops


    【解决方案1】:

    要在运行一定次数后停止它,只需在间隔中添加一个计数器,然后在达到该数字时清除它。

    例如

    var timesRun = 0;
    var interval = setInterval(function(){
        timesRun += 1;
        if(timesRun === 60){
            clearInterval(interval);
        }
        //do whatever here..
    }, 2000); 
    

    如果您想在设定的时间过去(例如 1 分钟)后停止它,您可以这样做:

    var startTime = new Date().getTime();
    var interval = setInterval(function(){
        if(new Date().getTime() - startTime > 60000){
            clearInterval(interval);
            return;
        }
        //do whatever here..
    }, 2000);     
    

    【讨论】:

    • 但是如果//do whatever here 花费的时间超过 2 秒呢?
    • 没关系,它是同步的——它会做函数中的东西然后等待2s。所以整个事情的运行次数将超过 2s。
    • 她在做动画。除非您将函数放入动画的回调中,否则您的函数不会等待动画完成。
    • 对不起,我现在明白了 - 如果循环中的位开始一个可能需要 2 秒以上的异步动画,你知道了 - 是的,在这种情况下,最好像你建议的那样使用超时,但我猜猜这不是问题要问的具体内容。
    • 我得到了第二个工作!所以现在我可以调整并让动画在一段时间后停止:)
    【解决方案2】:

    使用clearInterval 清除间隔。您需要传递从 setInterval 方法获得的区间 id。

    例如

    var intervalId = setInterval(function(){
                        ....
                     }, 1000);
    

    要清除上述间隔使用

    clearInterval(intervalId);
    

    您可以如下更改您的代码。

    (function(){
    
        // List your words here:
        var words = [
            'Lärare',
            'Rektor',
            'Studievägledare',
            'Lärare',
            'Skolsyster',
            'Lärare',
            'Skolpsykolog',
            'Administratör'
            ], i = 0;
    
        var intervalId = setInterval(function(){
            $('#dennaText').fadeOut(function(){
                $(this).html(words[i=(i+1)%words.length]).fadeIn();
                if(i == words.length){//All the words are displayed clear interval
                     clearInterval(intervalId);
                }
            });
           // 2 seconds
        }, 2000);
    
    })();
    

    【讨论】:

      【解决方案3】:

      您应该考虑使用递归的setTimeout() 而不是setInterval() 来避免竞争条件。

      var fadecount = 1;
      (function interval(){  
          $('#dennaText').fadeOut(function(){
              $(this).html(words[i=(i+1)%words.length]).fadeIn('fast',function(){
                  if (fadecount < 30){
                      fadecount += 1;
                      setTimeout(interval, 2000);
                  }
              });
          });
      }());
      

      【讨论】:

      • 好点,虽然它看起来像这样不同,但我想你需要改变 2000 的值,通过花时间来完成动画。
      • 这取决于 OP。 2000 毫秒、1700 毫秒等等。在这一点上,这是一个配置调整。
      • 无限递归 setTimeout 最终会导致堆栈溢出:medium.com/@devinmpierce/recursive-settimeout-8eb953b02b98
      【解决方案4】:

      你可以改用setTimeout,这样更好:

      (function foo(){ // wrap everything in a self-invoking function, not to expose "times"
        times = 20; // how many times to run
        (function run(){
          // do your stuff, like print the iteration
          document.body.innerHTML = times;
      
          if( --times ) // 200 * 20 = 4 seconds
            setTimeout(run, 100);
        })();
      })();

      【讨论】:

      • 小心,因为递归 setTimeout 会导致堆栈溢出(错误,不是本站)。 medium.com/@devinmpierce/recursive-settimeout-8eb953b02b98
      • @PRMan 链接的文章使用挥手解释并且似乎是错误的:为过期超时所做的每个回调都来自带有新调用堆栈的事件循环。在这样的回调中调用setTimeout 不会导致堆栈溢出。
      【解决方案5】:

      最简单的解决方案是

      var intervalId =   setInterval(function() {
          $('#dennaText').fadeOut(function() {
              $(this).html(words[i = (i + 1) % words.length]).fadeIn();
          });
      }, 2000); // run every 2 seconds
      
      setTimeout(function(){
          clearInterval(intervalId);
      },10000) // stop it after 10seconds
      

      【讨论】:

        【解决方案6】:

        我正在使用 VueJs 并想在几秒钟后删除一个 div;这就是我所做的,我希望这可以帮助某人;)。

        export default {
          name: "Home",
          components: {},
          data() {
            return {
              removeAlert: false,
            };
          },
          methods: {
            removeAlertF() {
              let wait = window.setInterval(() => {
                this.removeAlert = true;
                console.log("done");
                if(true){
                  window.clearInterval(wait);
                }
              }, 3000);
            },
          },
          mounted() {
            this.loadData();
            this.removeAlertF();
          },
        };
        <style>
        .remove-alert {
          display: none;
        }
        </style>
         
         <div
                :class="removeAlert ? 'remove-alert' : ''"
                role="alert"
              >
                Data loaded successfully
              </div>

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-11-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-12-20
          相关资源
          最近更新 更多