在进入下一个循环迭代之前执行setTImeout操作

Perfoming setTImeout action before going to next loop iteration

本文关键字:执行 setTImeout 操作 迭代 下一个 循环      更新时间:2023-09-26

在序列中添加另一个步骤之前,我试图重复内存游戏simon中的模式,但我认为循环迭代得太快了,以至于序列中的每个数字都在基本上相同的时间调用setTimeout(函数,1000),然后它们同时播放,而不是一个接一个地播放。有办法解决这个问题吗?

function playPattern(){
    var i;
    for(i=0; i<pattern.length; i++){
        var currentNum = pattern[i];
        if(currentNum === 0){
            var greenNoise = new Audio("greenNoise.mp3");
            greenNoise.play();
            ctx.fillStyle = "#71FF4A";
            ctx.fillRect(10, 30, w/2-10, h/3);
            setTimeout(drawGameBoard, 1000);
        } else if (currentNum === 1){
            var redNoise = new Audio("redNoise.mp3");
            redNoise.play();
            ctx.fillStyle = "#F73B3E";
            ctx.fillRect(w/2, 30, w/2-10, h/3);
            setTimeout(drawGameBoard, 1000);    
        } else if (currentNum === 2){
            var yellowNoise = new Audio("yellowNoise.mp3");
            yellowNoise.play();
            ctx.fillStyle = "#FFF269";
            ctx.fillRect(10, h/3+30, w/2-10, h/3);          
            setTimeout(drawGameBoard, 1000);
        } else { //currentNum === 3
            var blueNoise = new Audio("blueNoise.mp3");
            blueNoise.play();
            ctx.fillStyle = "#58ACF5";
            ctx.fillRect(w/2, h/3+30, w/2-10, h/3);         
            setTimeout(drawGameBoard, 1000);
        }
    }
    setTimeout(increasePattern, 1000);
}

您是对的,所有函数都以相同的间隔排队。你可以通过将间隔乘以迭代次数来解决这个问题,例如

setTimeout(increasePattern, 1000 * i);

但这将使一堆函数排队以按顺序运行。相反,考虑让函数在选定的时间间隔调用自己,直到满足某些条件,例如

// This function does all the setup
function doStuff(num) {
  // Keep limit in a closure
  var limit = num;
  // This function does the work
  function realStuff() {
    // While limit is greater than zero, do stuff...
    if (limit) {
      // Decrement limit
      --limit;
      
      // Trivial thing to do
      console.log(limit);
      // Call itself again
      setTimeout(realStuff, 1000);
    }
  }
  // Initiate the first time
  realStuff();
}
doStuff(10);

你也可以调整每次通话的超时时间,看看你是否希望尽早尝试在长时间内达到更高的精度。您可以通过不调用下一个setTimeout来取消序列,或者通过在函数外部提供间隔标识符,从而可以通过调用clearTimeout来取消序列。