Javascript:使用setInterval同步迭代for循环

时间:2017-10-17 21:11:54

标签: javascript jquery asynchronous setinterval

我正在制作一个Simon Says计划,我遇到了调用计算机的一系列动作并在屏幕上显示它们的问题。

我正在尝试使用此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 个答案:

答案 0 :(得分: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一个有效的例子。

答案 1 :(得分:0)

这是使用异步/等待的另一种方式:

const timeout = ms => new Promise(res => setTimeout(res, ms));

(async () => {
  var i = 1;
  while (true) {
    await timeout(1000);
    // iteration logic
    console.log(i++);
    // termination logic
    if(i > 10) {
      break;
    }
  }
  console.log("done");
})();

此处设置的间隔完全被PromisesetTimeoutawait替换为while loop