下面是一段模拟实现 Promise.all 的代码,打五角星的这一行的 let n
如果定义在 for 循环外面的话,走回调 给 result 数组赋值的时候就不能获取到正确的 n,n 值始终是 iterator 的长度,这是为什么?
Promise.myAll = function (iterator) {
let res, rej
const p = new Promise((resolve, reject) => {
res = resolve
rej = reject
})
let count = 0
let fulfilledCount = 0
let result = []
const a = []
for (let ite of iterator) {
// ⭐️ 这一行
let n = count
count++
let b = Promise.resolve(ite).then((data) => {
fulfilledCount++
result[n] = data
if (fulfilledCount === count) {
res(result)
}
}, rej)
a.push(b)
}
console.log(a)
if (count === 0) {
res(result)
}
return p
}
Promise.myAll([1, 2, 3]).then(data => {
console.log(data)
})
如果题主把
let
声明的变量放在循环外部,那这个变量n
只会被声明一次,并且其值在每次迭代时不会更新。由于 JavaScript 的事件循环机制,在异步回调函数执行时会访问到 最后一次 循环结束时的 n 值(即iterator
的长度),导致无法正确地给result
数组赋值。为了解决这个问题,需要将
let n = count
放在循环内部,确保每次迭代都有一个 独立的 变量 n 来保存当前迭代项对应的索引值。