首页 > 解决方案 > For循环不会迭代

问题描述

我有一个可以完美运行的函数,直到我把它放在一个 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()
}

标签: javascriptfor-loopsettimeout

解决方案


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

幸运的是,您可以使用Promises 和async/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);
})();

推荐阅读