Javascript - clearInterval 在多个 setInterval 时不起作用
Javascript - clearInterval not working when multiple setInterval
我在使用 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.如何让代码正常运行?
编辑:
如果您只是想让代码正常工作,只需更改第二个代码段中的一行:
clearInterval(timeoutID); // stop the execution
到
clearInterval(IntervalID); // stop the execution
但是其他人的回答可以解决我在这个问题上的困惑。
问题是您的闭包中没有捕获正确的 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;
}
我在使用 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.如何让代码正常运行?
编辑:
如果您只是想让代码正常工作,只需更改第二个代码段中的一行:
clearInterval(timeoutID); // stop the execution
到
clearInterval(IntervalID); // stop the execution
但是其他人的回答可以解决我在这个问题上的困惑。
问题是您的闭包中没有捕获正确的 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;
}