2017-10-17 156 views
0

我正在開發一個Simon Says程序,我遇到了調用計算機的一系列移動並在屏幕上顯示它們的問題。Javascript:通過與setInterval同步循環遍歷循環

我正在嘗試使用此aiMoves()函數遍歷數組,並通過突出顯示適當的顏色按鈕來顯示每個移動。我試圖使用的setInterval使得第一按鈕突出,程序等待一秒鐘,然後像下一個按鈕突出這樣:

function aiTurns(randNum){ 
    for(var i = 0; i < aiMoves.length; i++) { 
    if(aiMoves[i] === 1){ 
     //sound1(); 
     $('#green').addClass("active"); 
     setTimeout(function(){ 
     $('#green').removeClass("active"); 
     }, 500); 
    } 
    else if(aiMoves[i] === 2){ 
     //sound2(); 
     $('#red').addClass("active"); 
     setTimeout(function(){ 
     $('#red').removeClass("active"); 
     }, 500); 
    } 
    else if(aiMoves[i] === 3) { 
     //sound3(); 
     $('#yellow').addClass("active"); 
     setTimeout(function(){ 
     $('#yellow').removeClass("active"); 
     }, 500); 
     } 
     else if(aiMoves[i] === 4){ 
     //sound4(); 
     $('#blue').addClass("active"); 
     setTimeout(function(){ 
     $('#blue').removeClass("active"); 
     }, 500); 
    } 
    level--; 
    playerTurn = true; 
    } 

}

我把它叫做是這樣的:

var moves = function() { 
aiTurns(randomNumber()); 

}

setInterval(moves, 2000); 
} 

問題是的setInterval是異步的所有迭代aiMoves()中的for循環同時被調用。我怎樣才能設置它,以便數組的第一個元素執行,暫停,然後下一個元素執行?

這裏是一個更好的可視化codepen: https://codepen.io/nick_kinlen/pen/oGjMMr?editors=0010

回答

2

由於for循環立即運行,直到完成,你需要一個不同的方式串聯運行的異步代碼。這裏有一個簡單的抽象,它可以讓你在給定的延遲陣列循環中的每個迭代之間:

function intervalForEach (array, iteratee, delay) { 
    let current = 0 

    let interval = setInterval(() => { 
    if (current === array.length) { 
     clearInterval(interval) 
    } else { 
     iteratee(array[current]) 
     current++ 
    } 
    }, delay) 
} 

你的所有條件邏輯可以去iteratee功能,它只是接受數組中的當前項目內。 Here's一個工作示例。

+0

謝謝!那就是訣竅。 –