do while loop with setTimeout causing infinite loop

六月ゝ 毕业季﹏ 提交于 2019-12-12 04:18:56

问题


I'm working on a simon game(the one you follow the color pattern). 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. The highlightDiv function just does a toggleClass on the div, then a setTimeout to toggle the class back off. 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. 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. This is the codepen if that is easier: 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);

回答1:


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. 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.

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.

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:

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

},
2000);



回答2:


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.




回答3:


You're incrementing a variable called i within the anonymous function delegate that you're passing to setTimeout. The locally-scoped variable i on which the do-while loop depends is never updated.

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.

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


来源:https://stackoverflow.com/questions/34600764/do-while-loop-with-settimeout-causing-infinite-loop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!