如何在一段时间或多次操作后停止 setInterval?

IT技术 javascript loops
2021-02-19 14:43:46

我通过使用此答案中的代码创建了一个“更改单词”的循环: jQuery:每隔几秒查找单词并更改一次

一段时间后如何停止?说是在 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);

})();
6个回答

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

例如

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);     
抱歉,我现在明白了 - 如果循环中的某个位开始一个可能需要 > 2 秒的异步动画,明白了 - 是的,在这种情况下,最好像您建议的那样使用超时,但我想这不是问题所在询问。
2021-04-27 14:43:46
她在做动画。除非您将函数放入动画的回调中,否则您的函数不会等待动画完成。
2021-04-30 14:43:46
我让第二个工作了!所以现在我可以调整和制作,以便动画在一段时间后停止:)
2021-05-06 14:43:46
没关系,它是同步的——它会做函数中的东西,然后它会等待 2 秒。所以整个事情将花费超过运行次数 2s 的时间。
2021-05-15 14:43:46
但是如果//do whatever here时间超过 2 秒呢?
2021-05-16 14:43:46

使用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);

})();

您应该考虑使用递归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);
            }
        });
    });
}());
无休止的递归 setTimeout 最终会导致堆栈溢出:medium.com/@devinmpierce/recursive-settimeout-8eb953b02b98
2021-04-19 14:43:46
这取决于OP。2000 毫秒,1700 毫秒,等等。在这一点上,这是一个配置调整。
2021-05-08 14:43:46
好点,虽然它看起来像这样不同,但我想你需要改变 2000 值,通过花时间完成动画。
2021-05-15 14:43:46

您可以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);
  })();
})();

@PRMan 链接的文章使用挥手解释并且似乎是错误的:为过期超时所做的每个回调都来自具有新调用堆栈的事件循环。调用setTimeout从这样的回调中不会导致堆栈溢出。
2021-04-19 14:43:46
小心,因为递归 setTimeout 会导致堆栈溢出(错误,不是这个站点)。medium.com/@devinmpierce/recursive-settimeout-8eb953b02b98
2021-05-13 14:43:46

我正在使用 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>