For 循环不会迭代

时间:2021-05-30 15:31:55

标签: javascript for-loop settimeout

我有一个完美运行的函数,直到我将它放入 for 循环中 - 那时我在 Safari 中收到一个参考错误(找不到 i)。在 Chrome 和 Firefox 中,它仅在第一次迭代时运行(即 i = 0)。怎么回事?

编辑:这里 for 循环的重点是在其中的函数(包括超时)完成时进行迭代。如果有人对如何做到这一点有其他建议,那就太好了。

没有for循环的函数:

let realScores = [40,7, 3, 2]
let scores = [0,0,0,0]
  
  let i = 0
  let counter = 0
  function timer() {
    setTimeout(() => {
      scores[i]++
      console.log(i, scores[i])
      if (scores[i] < realScores[i]) {
        timer()
      }
    }, 10)
  }
  timer()

还有 for 循环:

let realScores = [40,7, 3, 2]
let scores = [0,0,0,0]

for (let i = 0; i < scores.length; i++) {
  let counter = 0
  function timer() {
    setTimeout(() => {
      scores[i]++
      console.log(i, scores[i])
      if (scores[i] < realScores[i]) {
        timer()
      }
    }, 10)
  }
  timer()
}

1 个答案:

答案 0 :(得分:0)

For 循环是同步的,这意味着它们将在 setTimeout 完成之前执行 - 您不能停止 for 循环的执行以等待 setTimeout 回调的解析。

幸运的是,您可以使用 Promiseasync/await 来阻止 for 循环的执行以等待 setTimeout 解析:

let realScores = [40,7, 3, 2]
let scores = [0,0,0,0]

function timer(i) {
  return new Promise((resolve, reject) => {
    const t = () => {
      setTimeout(() => {
        scores[i]++;
        console.log(i, scores[i])
        if (scores[i] < realScores[i]) {
          t();
        } else {
          resolve();
        }
      }, 10);
    }
    t();
  }); 
}
(async() => {
  for (let i = 0; i < scores.length; i++) {
  let counter = 0;
  await timer(i);
}
console.log(scores);
})();