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; 
}