Javascript 即使调用了clearInterval,interval也会继续启动

Javascript 即使调用了clearInterval,interval也会继续启动,javascript,for-loop,setinterval,infinite-loop,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); (i=0;i)的 此行每次创建一个新的in

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

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

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

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

function pauseAndRepeat(delay, iterations, func) {
    var i = 0;
    var interval = setInterval(function() {
        func();
        if(++i === iterations) {
            clearInterval(interval);
        }
    }, delay);    
}
pauseAndRepeat(1000, 10, function() {
    console.log("Function ran");
});
这里我们有一个函数,它在其局部作用域中定义了一个计数器(
i
),然后它使用一个函数创建一个间隔,该函数检查计数器是否应该调用您的函数(
func
)或者在完成时清除间隔。
interval
将在实际调用间隔处理程序时设置。在这种情况下,处理程序基本上是一个闭包,因为它绑定到
pauseAndRepeat
的局部范围

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

function pauseAndRepeat(delay, iterations, func) {
    var i = 0;
    var interval = setInterval(function() {
        func();
        if(++i === iterations) {
            clearInterval(interval);
        }
    }, delay);    
}
pauseAndRepeat(1000, 10, function() {
    console.log("Function ran");
});
这将打印出
函数运行十次,每次暂停一秒钟

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

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

function pauseAndRepeat(delay, iterations, func) {
    var i = 0;
    var interval = setInterval(function() {
        func();
        if(++i === iterations) {
            clearInterval(interval);
        }
    }, delay);    
}
pauseAndRepeat(1000, 10, function() {
    console.log("Function ran");
});
这里我们有一个函数,它在其局部作用域中定义了一个计数器(
i
),然后它使用一个函数创建一个间隔,该函数检查计数器是否应该调用您的函数(
func
)或者在完成时清除间隔。
interval
将在实际调用间隔处理程序时设置。在这种情况下,处理程序基本上是一个闭包,因为它绑定到
pauseAndRepeat
的局部范围

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

function pauseAndRepeat(delay, iterations, func) {
    var i = 0;
    var interval = setInterval(function() {
        func();
        if(++i === iterations) {
            clearInterval(interval);
        }
    }, delay);    
}
pauseAndRepeat(1000, 10, function() {
    console.log("Function ran");
});

这将打印出
函数运行十次,每次暂停一秒钟。

setInterval
预计将以一个间隔永远运行。每次在此处调用
setInterval
时,您都会有一个新的无限循环每10秒运行一次函数,正如其他人所指出的,您只会取消最后一个循环

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

var counter = 0;

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

next();

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

setInterval
预计将在一个间隔上永远运行。每次在此处调用
setInterval
,您都会有一个新的无限循环每10秒运行一次您的函数,以及其他循环注意到您只取消了最后一个

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

var counter = 0;

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

next();

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

setInterval不会阻塞!您刚刚创建了10个间隔,并每次覆盖
interval
变量,因此这10个间隔中只有一个可以引用并停止,是最后一个SetInterval不阻塞!您刚刚创建了10个interval,并且每次都会覆盖
interval
变量,因此在这10个interval中,您只有最后一个可以引用并停止