打破setTimeout循环

Mar*_*ijn 12 javascript node.js

我在打破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);

    }
Run Code Online (Sandbox Code Playgroud)

我读过100个与setTimeout相关的帖子,但是无法想出这个帖子.

编辑:

当我想要完成时,让我澄清一下.

我的游戏有75个转弯,每个转弯需要大约500毫秒,在那个转弯期间我想检查条件是否满足并宣布玩家赢了,在玩家赢了之后没有必要继续剩下的转弯.

Jos*_*ber 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);
Run Code Online (Sandbox Code Playgroud)

如果您的转弯需要500毫秒,请将最后一个更改100500.


Ila*_*mer 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); 
Run Code Online (Sandbox Code Playgroud)

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); 
Run Code Online (Sandbox Code Playgroud)

  • 我看到这里没有递归.也许是复发.此外,这种技术往往会给时钟增加一个漂移,这在特定情况下似乎是不可取的. (2认同)
  • 在后一篇博客文章中非常教条.看起来更像是这样的人在异步执行时感到不安并且注意到Ajax调用(顺便说一下,它不需要任何超时).恕我直言,你最好在尝试解决异步执行之前知道自己在做什么,无论是周期性还是单次定时器. (2认同)
  • 写"setInterval有害"之类的东西对我来说听起来很偏执.暗示你不能/不应该使用setInterval来"做一些异步"并不意味着什么.说你无法处理定期计时器中的错误是完全错误的.对于帧丢弃,这可能正是您想要的,例如定期刷新显示或一组数据时.setInterval是某些工作的正确工具,不适合其他工作,这就是全部. (2认同)

San*_*lla 5

我认为最好使用 setInterval 而不是 setTimeout。

为了清除它们,您将它们分配给一个变量,然后使用

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

clearTimeout(myVar);
clearInterval(myVar2);
Run Code Online (Sandbox Code Playgroud)