Выход из цикла setTimeout

У меня возникли проблемы с выходом из цикла setTimeout.

    for (var i = 0; i < 75; i++) {

        setTimeout(function(i) {

            return function() {

                console.log("turn no. " + i);

                if(table.game.playerWon) {
                    console.log('Player won');
                    // I want to stop the loop now
                    // i = 75; didn't work
                }

            };

        }(i), 100*i);

    }

Я прочитал как 100 сообщений, связанных с setTimeout, но не могу понять это.

изменить:

позвольте мне уточнить немного, когда я пытаюсь выполнить.

моя игра имеет 75 ходов, каждый ход должен занять около 500 мс, во время этого хода я хочу проверить, выполнено ли условие и объявить, что игрок выиграл, после того, как игрок выиграл, нет необходимости продолжать остальную часть витки.

4 ответов


вместо установки всех этих таймеров создайте один непрерывный таймер с setInterval:

var counter = 0;

var timer = setInterval(function () {

    console.log("turn no. " + counter);

    if (table.game.playerWon) {
        console.log('Player won');
    }

    if (counter >= 75 || table.game.playerWon) {
        clearInterval(timer);
    }

    counter++;

}, 100);

если ваши очереди должны занять 500 мс, измените это последнее 100 to 500.


вы не должны использовать цикл for, просто рекурсивный setTimeout

setInterval не подходит для очень многих вещей:

  • если произошла ошибка, вы не можете остановить поезд.
  • Если вам нужны различные исполнения шагов.
  • Если вам нужно передать данные в сеть.
  • Если вам нужно сделать что-то асинхронное.
  • и хуже всего - SETINTERVAL НЕ ГАРАНТИРУЕТ ВЫПОЛНЕНИЕ
  • поэтому используйте его, только если вы знаете, что делаете!

устранение:

var func = function(i){

    return function(){
        if (i >= 75) return;
        console.log("turn no. " + i);

        if(table.game.playerWon) {
            console.log('Player won');
        } else {
            setTimeout(func(++i), 500); 
        }

    }   
}

setTimeout(func(0), 500); 

вы можете запустить его в node.js если вы хотите проверить, как это работает:

var winTurn = 10;

var func = function(i){

    return function(){
        if (i >= 75) return;
        console.log("turn no. " + i);

        if(i === winTurn) {
            console.log('Player won');
        } else {
            setTimeout(func(++i), 50); 
        }

    }   
}

setTimeout(func(1), 50); 

Я думаю, было бы лучше использовать setInterval вместо setTimeout.

и для очистки обоих из них вы назначаете их переменной, а затем очищаете тайм-аут с помощью

var myVar = setTimeout(func, time);
var myVar2 = setInterval(func, time);

clearTimeout(myVar);
clearInterval(myVar2);

вот пример того, что вы должны написать

var timeouts = [];
for (var i = 0; i < 75; i++) {

    timeouts[i] = setTimeout(function(i) {

        return function() {

            console.log("turn no. " + i);

            if(table.game.playerWon) {
                console.log('Player won');
                // I want to stop the loop now
                for(var k = i; k < timeouts.length; k++) {
                    clearTimeout(timeouts[i]);
                }
            }

        };

    }(i), 100*i);

}

еще проще решение-это вызов только setTimeout, когда table.game.playerWon - Это ложь.

var timeoutFunction = function(i) {

    return function() {

        console.log("turn no. " + i);

        if(table.game.playerWon) {
            console.log('Player won');
            // Game stopped
        } else {
            timeout = setTimeout(timeoutFunction(i+1), 100);  
        }
    };

}

var timeout = setTimeout(timeoutFunction(0), 100);

надеюсь, что это помогает