即使已调用clearInterval,interval仍会继续触发

时间:2016-01-13 00:34:59

标签: javascript for-loop setinterval infinite-loop

我试图让一个函数在每次运行之间暂停运行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”后重复无限次

2 个答案:

答案 0 :(得分:2)

interval = setInterval(function() {console.log("Function ran");}, 1000);

此行每次都会创建一个新的interval-instance,这意味着您已创建了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-handler时,将设置interval。在这种情况下,处理程序基本上是一个闭包,因为它绑定到pauseAndRepeat的本地范围。

然后您可以按如下方式调用该函数:

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

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

答案 1 :(得分:1)

预计

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

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