【问题标题】:interval keeps firing even though clearInterval has been called即使 clearInterval 已被调用,interval 也会继续触发
【发布时间】:2016-01-13 00:34:59
【问题描述】:

我试图让一个函数运行 10 次,每次运行之间都有一个暂停,但是当我尝试它时,它会无限次重复该函数,然后在 10 次后暂停,依此类推。现在这是有问题的代码:

for(i=0;i<10;i++) {
    console.log(i);
    interval = setInterval(function() {console.log("Function ran");}, 1000);
}
window.clearInterval(interval);

控制台:
0
1
2
3
4
5
6
7
8
9
函数运行

[“函数运行”在“9”之后无限次重复]

【问题讨论】:

  • setInterval 不会阻塞!
  • 您刚刚创建了 10 个区间,并且每次都覆盖了 interval 变量,所以这 10 个区间中只有一个您可以参考并且可以停止的区间是最后一个

标签: javascript for-loop setinterval infinite-loop


【解决方案1】:
interval = setInterval(function() {console.log("Function ran");}, 1000);

此行每次都会创建一个新的区间实例,这意味着您已经创建了 10 个区间。在循环结束时,interval 保存了最后创建的间隔的 id。因此,这是您正在清除的唯一一个,而其他的仍在运行。

要取消间隔,您需要跟踪函数已被调用的次数。一种方法如下:

function pauseAndRepeat(delay, iterations, func) {
    var i = 0;
    var interval = setInterval(function() {
        func();
        if(++i === iterations) {
            clearInterval(interval);
        }
    }, delay);    
}

这里我们有一个函数在其本地范围内定义了一个计数器 (i)。然后它使用一个检查计数器的函数创建一个间隔,看看它是否应该调用您的函数 (func) 或在完成后清除间隔。 interval 将在实际调用间隔处理程序时设置。在这种情况下,处理程序基本上是一个闭包,因为它绑定到 pauseAndRepeat 的本地范围。

然后就可以调用如下函数了:

pauseAndRepeat(1000, 10, function() {
    console.log("Function ran");
});

这将打印出Function ran 十次,每次暂停一秒钟。

【讨论】:

    【解决方案2】:

    setInterval 预计会在一定间隔内永远运行。每次您在这里调用setInterval 时,您都会有一个新的无限循环每 10 秒运行一次您的函数,并且正如其他人所指出的,您只是取消了最后一个。

    链式调用setTimeout 可能会做得更好:

    var counter = 0;
    
    function next() {
        if (counter < 10) {
            counter++;
            setTimeout(function() {
                console.log("Function ran");
                next();
            }, 1000);
        }
    }
    
    next();
    

    这会链接延迟函数,在每次运行后为下一个函数设置超时。您可以使用 setInterval 和取消执行类似的操作:

    var counter = 0;
    
    var intervalId = setInterval(function() {
        console.log("Function ran");
        if (++counter >= 10) {
            clearInterval(intervalId);
        }
    }, 1000);
    

    在这两种情况下,关键问题是您触发下一次运行或取消间隔在回调函数中,而不是在同步代码中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-27
      • 1970-01-01
      • 2017-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多