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

javascript node.js

19928 просмотра

4 ответа

У меня возникли проблемы с выходом из цикла 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 мс, в течение этого хода я хочу проверить, выполнено ли условие, и объявить, что игрок выиграл, после того, как игрок выиграл, нет необходимости продолжать оставшиеся ходы.

Автор: Martijn Источник Размещён: 12.11.2019 09:48

Ответы (4)


19 плюса

Решение

Вместо установки всех этих таймеров создайте один непрерывный таймер с помощью 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на 500.

Автор: Joseph Silber Размещён: 20.01.2014 05:56

11 плюса

Вы не должны использовать цикл 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); 
Автор: Ilan Frumer Размещён: 20.01.2014 06:00

2 плюса

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

И для очистки их обоих вы назначаете их переменной, а затем очищаете время ожидания с

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

clearTimeout(myVar);
clearInterval(myVar2);
Автор: Santiago Rebella Размещён: 20.01.2014 05:58

0 плюса

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

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

Надеюсь, это поможет

Автор: php-dev Размещён: 20.01.2014 05:56
Вопросы из категории :
32x32