【问题标题】:do while loop with setTimeout causing infinite loop使用 setTimeout 执行 while 循环导致无限循环
【发布时间】:2016-01-05 06:42:47
【问题描述】:

我正在开发一款 simon 游戏(您遵循颜色模式的游戏)。它通过计算机的第一轮和我的第一轮,但是尝试在每个计算机选择之间执行 setTimeout 会导致使用 do while 语句的无限循环,或者如果我使用 for 循环,则同时播放两个选择。 highlightDiv 函数只是在 div 上执行一个 toggleClass,然后是一个 setTimeout 来关闭该类。 audioStart 函数使用 switch 语句来确定播放哪个声音,然后设置半秒的 setTimeout 来播放该声音。我认为增量上的这个 setTimeout 将允许有足够的时间让这两件事在它增量之前发生,然后在 computerChoice 数组中执行下一个索引。如果这更容易的话,这就是 codepen:http://codepen.io/RawleJuglal/pen/pgRVKd

var computerChoice = ["red", "yellow"],index=0;

function computerPattern(cPattern, index){
 console.log("Entered computer pattern function");
 console.log("This is cPattern");
 console.log(cPattern);
 console.log("This is index: "+ index);
 if(index !== cPattern.length)
   {
     highlightDiv(cPattern[index]);
     audioStart(cPattern[index]);
     index++;
     computerPattern(cPattern, index);
   }
 else
   {
     index=0;
   }
 console.log("Leaving computerPattern function");
}

computerPattern(computerChoice, index);

【问题讨论】:

  • 只是提醒一下,我已经根据 Cecilio 的回答更改了此代码,但从那时起我正在查看其他答案,看看这些是否会是更好的解决方案,因为我的函数仍然执行得太快。谢谢大家的回复!

标签: javascript settimeout do-while


【解决方案1】:

Javascript 是单线程的,超时的概念意味着您将一个函数放在一个特殊的队列上,即在时间到期时执行您的回调。现在,由于在您的代码中,i 变量仅在 timeout 函数中更新,仅在 3 秒后更新,这意味着循环体将一次又一次地运行,直到 3 秒满足。

在 3 秒内,javascript 可以运行数千次迭代,并且每次迭代都会注册另一个超时,这意味着您的事件队列已被炸毁,您的单线程将很难完成所有这些任务,直到我最终到达 cPattern.length,如果有的话。

您的解决方案可能正在使用某种setInterval,它有一个回调,可以执行您想要的操作,并在每次递增的某个迭代变量上停止,让我们这样说:

var interval = setInterval(function(){
     console.log(cPattern[i]);
     highlightDiv(cPattern[i]);
     audioStart(cPattern[i]);
     i++;
     if(i >= cPattern.length){
        clearInterval(interval);
     } 

},
2000);

【讨论】:

    【解决方案2】:

    永远不会调用您的超时函数,因为您没有给它机会。只要您的代码正在运行(您的循环),浏览器就无法运行使用同一线程的预定脚本。您将不得不重新考虑代码。

    【讨论】:

      【解决方案3】:

      您在传递给 setTimeout 的匿名函数委托中增加了一个名为 i 的变量。 do-while 循环所依赖的局部范围变量i 永远不会更新。

      根据您要查找的功能,您可以在变量 i 仍在作用域内时递增它,然后使用闭包将其值的快照传递给 setTimeout 函数委托。

      function run(){
        var i = 0
        do{
          (function(i){
            setTimeout(function(){
               alert(i);
            },1000);
          })(i++)
        }
        while(i < 2);
      }
      run(); 
      

      【讨论】:

        猜你喜欢
        • 2012-08-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-14
        • 2016-06-05
        • 1970-01-01
        • 1970-01-01
        • 2013-08-26
        相关资源
        最近更新 更多