【问题标题】:Javascript - clearInterval not working when multiple setIntervalJavascript - 多个 setInterval 时 clearInterval 不起作用
【发布时间】: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,所以它还在继续)。

标签: javascript setinterval clearinterval


【解决方案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,所有元素/间隔都不能停止。
猜你喜欢
  • 1970-01-01
  • 2021-12-20
  • 2021-05-18
  • 1970-01-01
  • 2013-09-28
  • 1970-01-01
  • 2021-07-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多