我在setInterval&中遇到了一些问题clearInterval。
在我的代码中,我设置了多个间隔,当count减少到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
但其他人的回答可以解决我在这个问题上的困惑。
答案 0 :(得分:0)
问题是你的闭包中没有捕获正确的 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;
}