SetInterval не останавливается после clearInterval

У меня вот такой код:

var mainGame = setInterval(() => {
    carArr.forEach((elem) => {
        var currentPosition = parseInt(elem.css("margin-left"));

        if (currentPosition > window.innerWidth * 0.8) {
            alert("BOTS WINS! YOU ARE LOSER!");
            console.log("Stopping game..."); // Debug log
            clearInterval(mainGame); // Should stop here
            return; // Exit the loop early
        }

        elem.css({ "margin-left": (currentPosition + 1) + "px" });
    });
}, 50);

когда наступает событие, SetInterval не останавливается. Почему так?


Ответы (1 шт):

Автор решения: Solt

return не сработает, следовательно цикл будет показывать alert по кругу. Да ещё и внутри асинхронной функции, выполняемой каждые 50мс. Думаю, там просто накапливаются алерты. Я бы переделал цикл на for(elem of carArr) а внутри по условию break. Ну а алерт, конечно вне цикла и после остановки таймера. Кроме того, если есть вероятность, что частота вызовов превысит время выполнения, лучше обезопасить себя флагом, запрещающим выполнение нескольких экземпляров "внахлёст".

    var is_checking=0;    
    var mainGame = setInterval(() => {
        if(is_checking) return;
        is_checking=1;
        let stop=0;
        for(elem of carArr){
            var currentPosition = parseInt(elem.css("margin-left"));
    
            if (currentPosition > window.innerWidth * 0.8) {
                clearInterval(mainGame); // Should stop here
                stop=1;
                break; // Exit the loop early
            }
        }
        if(stop){
            alert("BOTS WINS! YOU ARE LOSER!");
            console.log("Stopping game..."); // Debug log
            elem.css({ "margin-left": (currentPosition + 1) + "px" });
        }
        is_checking=0;

    }, 50);

А если всё-таки хочется обходить массив итерирующими методами, то подойдёт carArr.some((item)=>...). Если делать выход return true - он прервётся.

→ Ссылка