2017-10-17 353 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

谢谢!那就是诀窍。 –