我有一个完美运行的函数,直到我将它放入 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()
}
答案 0 :(得分:0)
For 循环是同步的,这意味着它们将在 setTimeout
完成之前执行 - 您不能停止 for 循环的执行以等待 setTimeout
回调的解析。
幸运的是,您可以使用 Promise
和 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);
})();