簡體   English   中英

使用setTimeout進行while循環會導致無限循環

[英]do while loop with setTimeout causing infinite loop

我正在開發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);

永遠不會調用您的超時函數,因為您沒有機會。 只要您的代碼正在運行(循環),瀏覽器就無法運行使用同一線程的計划腳本。 您將不得不重新考慮代碼。

Javascript是單線程的,超時的概念意味着您將一個函數放在一個特殊的隊列中,該隊列將在到期時執行回調。 現在,由於在您的代碼中,僅在3秒鍾后才在超時函數中更新i變量,這意味着循環主體將一次又一次地運行,直到滿足3秒鍾為止。

在3秒鍾內,javascript可以運行數千次迭代,並且每次迭代都會注冊另一個超時,這意味着事件隊列被cPattern.length ,並且單線程將很難完成所有這些任務,直到我最終達到cPattern.length為止。

您的解決方案可能使用了setInterval ,該setInterval的回調函數可以執行您想要的操作,並在每次迭代變量停止時都遞增,就像這樣:

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

},
2000);

您要在傳遞給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(); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM