简体   繁体   English

使用setTimeout进行while循环会导致无限循环

[英]do while loop with setTimeout causing infinite loop

I'm working on a simon game(the one you follow the color pattern). 我正在开发simon游戏(一种遵循颜色模式的游戏)。 It makes it through the computers 1st turn and my 1st turn but trying to do a setTimeout between each computer choice is causing an infinite loop with the do while statement or playing both choices at the same time if I use for loop. 它通过计算机第一轮和我的第一轮,但是尝试在每个计算机选择之间执行setTimeout会导致使用do while语句导致无限循环,或者如果我使用for循环,则同时播放两个选择。 The highlightDiv function just does a toggleClass on the div, then a setTimeout to toggle the class back off. highlightDiv函数仅在div上执行toggleClass,然后执行setTimeout将类切换回关闭状态。 And the audioStart function uses a switch statement to determine which sound to play and then a setTimeout of half a second to play that sound. audioStart函数使用switch语句确定要播放的声音,然后使用setTimeout半秒钟播放该声音。 I thought this setTimeout on the increment would allow enough time for those two things to happen before it incremented and then did the next index in the computerChoice array. 我认为此setTimeout在增量上将允许足够的时间使这两种情况发生,然后再递增,然后在computerChoice数组中进行下一个索引。 This is the codepen if that is easier: http://codepen.io/RawleJuglal/pen/pgRVKd 如果这样更容易,可以使用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);

Your timeout function is never called because you don't give it a chance. 永远不会调用您的超时函数,因为您没有机会。 As long as your code is running (your loop), the browser can't run the scheduled scripts, which use the same thread. 只要您的代码正在运行(循环),浏览器就无法运行使用同一线程的计划脚本。 You will have to rethink the code. 您将不得不重新考虑代码。

Javascript is single threaded, and the concept of timeouts means that you place a function on a special queue, which is to execute your callbacks when their time is due. Javascript是单线程的,超时的概念意味着您将一个函数放在一个特殊的队列中,该队列将在到期时执行回调。 now, since in your code, the i variable is being updated only in the timeout function, which is only after 3 seconds, it means that the body of the loop will run again and again until 3 seconds are met. 现在,由于在您的代码中,仅在3秒钟后才在超时函数中更新i变量,这意味着循环主体将一次又一次地运行,直到满足3秒钟为止。

in 3 seconds, javascript can run thousands of iterations, and each iteration registers another timeout, which means that your event queue is blasted and your single thread will have hard time completing all those tasks until i is finally reaching cPattern.length , if ever. 在3秒钟内,javascript可以运行数千次迭代,并且每次迭代都会注册另一个超时,这意味着事件队列被cPattern.length ,并且单线程将很难完成所有这些任务,直到我最终达到cPattern.length为止。

your solution might be using some sort of setInterval which has a callback that does what you want, and stops on some iteration variable that increments every time, let's say like this: 您的解决方案可能使用了setInterval ,该setInterval的回调函数可以执行您想要的操作,并在每次迭代变量停止时都递增,就像这样:

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

},
2000);

You're incrementing a variable called i within the anonymous function delegate that you're passing to setTimeout. 您要在传递给setTimeout的匿名函数委托中递增一个名为i的变量。 The locally-scoped variable i on which the do-while loop depends is never updated. do-while循环所依赖的局部作用域变量i永远不会更新。

Depending on the functionality you're looking for, you can increment the variable i while it's still in scope, then use a closure to pass a snapshot of its value to the setTimeout function delegate. 根据所需的功能,可以在变量i仍在作用域内时对其进行递增,然后使用闭包将其值的快照传递给setTimeout函数委托。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM