2016-01-04 57 views
0

我正在一個西蒙遊戲(你遵循的顏色模式)。它通過計算機第一回合和我的第一回合,但試圖在每個計算機選擇之間執行setTimeout導致與do while語句的無限循環,或者如果我使用for循環同時播放兩個選項。 highlightDiv函數僅在div上執行toggleClass,然後使用setTimeout將類切換回去。 audioStart函數使用switch語句來確定要播放哪個聲音,然後使用setTimeout來播放該聲音。我認爲這個setTimeout增量會讓這兩件事發生之前有足夠的時間來增加,然後在computerChoice數組中執行下一個索引。這是codepen如果是比較容易:http://codepen.io/RawleJuglal/pen/pgRVKd做與setTimeout循環造成無限循環

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); 
+0

剛擡起頭我已經根據Cecilio的回答改變了這段代碼,但是我從那時起查看了其他答案,看看那些會是更好的解決方案,因爲我的函數仍然執行得太快,謝謝大家的迴應! –

回答

2

JavaScript是單線程的,和超時的概念,意味着你將一個函數在一個特殊的隊列,這是當他們的時間是由於執行您的回調。現在,因爲在你的代碼中,i變量只在超時函數中更新,這只是在3秒之後,這意味着循環的主體會一直運行,直到滿足3秒。

在3秒內,javascript可以運行數千次迭代,並且每次迭代都會記錄另一次超時,這意味着您的事件隊列被爆炸,並且您的單個線程將很難完成所有這些任務,直到我終於到達cPattern.length,if永遠。

您的解決方案可能會使用某種setInterval其中有一個回調,你想要什麼,並停在遞增每次一些迭代變量,讓我們這樣說:

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

}, 
2000); 
2

你超時功能,從來沒有所謂的,因爲你不給它一個機會。只要您的代碼正在運行(您的循環),瀏覽器就無法運行使用相同線程的預定腳本。你將不得不重新考慮代碼。

0

您正在增加一個名爲i的變量,該變量位於您傳遞給setTimeout的匿名函數委託中。 do-while循環所依賴的本地範圍變量i從不更新。

根據您要查找的功能,您可以在變量仍在範圍內時遞增變量i,然後使用閉包將其值的快照傳遞給setTimeout函數委託。

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