Promise.all 的实现?作用域问题?

下面是一段模拟实现 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)
})
阅读 2k
1 个回答

如果题主把 let 声明的变量放在循环外部,那这个变量 n 只会被声明一次,并且其值在每次迭代时不会更新。由于 JavaScript 的事件循环机制,在异步回调函数执行时会访问到 最后一次 循环结束时的 n 值(即 iterator 的长度),导致无法正确地给 result 数组赋值。

为了解决这个问题,需要将 let n = count 放在循环内部,确保每次迭代都有一个 独立的 变量 n 来保存当前迭代项对应的索引值。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题