Javascript - 多个 setInterval 时 clearInterval 不起作用
Posted
技术标签:
【中文标题】Javascript - 多个 setInterval 时 clearInterval 不起作用【英文标题】:Javascript - clearInterval not working when multiple setInterval 【发布时间】:2016-11-04 16:32:25 【问题描述】:我遇到了 setInterval 和 clearInterval 的问题。 在我的代码中,我设置了多个间隔,当计数减少到 0 时,停止执行。
如下:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0" charset="utf-8">
</head>
<body>
<body>
<script type="text/javascript">
for (var i=0; i<4; i++)
var count = 100;
var IntervalID = window.setInterval((function() // closure
var timeoutID = IntervalID; // temp
var countTemp = count; // temp
var id = i;
return function()
countTemp --;
console.log(id + " " + countTemp);
// do something here
if ( countTemp == 0 )
clearInterval(timeoutID); // stop the execution
console.log(id + " stop");
)(), 20);
</script>
</body>
</html>
控制台出现停止消息“x stop”后,除最后一个元素(id:3)外,所有元素都停止,它还在继续。
我尝试以另一种形式编写我的代码:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0" charset="utf-8">
</head>
<body>
<script type="text/javascript">
for (var i=0; i<4; i++)
doSomething(i);
function doSomething(id)
var count = 100;
var IntervalID = window.setInterval((function() // closure
var timeoutID = IntervalID; // temp
var countTemp = count; // temp
return function()
countTemp --;
console.log(id + " " + countTemp);
// do something here
if ( countTemp == 0 )
clearInterval(timeoutID); // stop the execution
console.log(id + " stop");
)(), 20);
</script>
</body>
</html>
但这一次,所有元素都不会停止。
我有两个问题: 1. 这两个代码有什么区别? 2.如何让代码正常工作?
编辑: 如果只是想让代码正常工作,只需要在第二个sn-p中改一行:
clearInterval(timeoutID); // stop the execution
到
clearInterval(IntervalID); // stop the execution
但是其他人的回答可以解决我在这个问题上的困惑。
【问题讨论】:
您尝试使用 IntervalID-s 时的值是多少? Console.log 那一项,就在 var timeoutID = IntervalID; 的下方; 在第一个 sn-p 中,timeoutID
未定义 i==0
,因为对 setInterval 的调用尚未完成。因此,在var timeoutID = IntervalID; // temp
上方添加console.log(i + " - " + IntervalID);
将显示0 - undefined
,然后是1 - 1
、2 - 2
、3 - 3
哦,我明白了一部分,在第一个sn-p中,当countTemp
减少到0时,clearInterval(timeoutID);
实际上停止了前一个(在id==1
部分,它停止id==0
执行; id==2
stop id==1
; 等等。但是没有一个停止id==3
,所以它还在继续)。
【参考方案1】:
问题是闭包中没有捕获正确的 IntervalID,当你的闭包运行时,window.setInterval 还没有返回 id,因为赋值表达式还没有完成。
一个简单的技巧可以用于对象,因为它们在 JavaScript 中通过引用传递给函数
我已经修改了循环来完成这个
for (var i=0; i < 4; i++)
var count = 100;
var args = id: i, counter: count ;
var IntervalID = window.setInterval((function(args) // closure
return function()
args.counter--;
console.log(args.id + " " + args.counter)
if ( args.counter == 0 )
clearInterval(args.IntervalID); // stop the execution
console.log(args.id + " stop");
.bind(args);
)(args), 20);
// by now the correct IntervalID will be captured
// as the assignment expression has finished executing
args.IntervalID = IntervalID;
【讨论】:
谢谢,现在我明白了。回答我自己的问题 1,在第一个 sn-p 中,timeoutID
捕获保留在内存中的前一个 IntervalID
,所以只有最后一个不能停止。在第二个sn-p中,调用一个函数,完成后从函数栈中弹出,所以timeoutID
不能捕获任何值,是undefined
,所有元素/间隔都不能停止。以上是关于Javascript - 多个 setInterval 时 clearInterval 不起作用的主要内容,如果未能解决你的问题,请参考以下文章
mobile-safari javascript:多个 setTimeouts 或 setIntervals