实现 Promise.allSettled

Huy小于 1 分钟javascriptjavascript

在 MDN 上, 对 Promise.allSettled 的解释是: Promise.allSettled() 静态方法将一个 Promise 可迭代对象作为输入,并返回一个单独的 Promise。当所有输入的 Promise 都已敲定时(包括传入空的可迭代对象时),返回的 Promise 将被兑现,并带有描述每个 Promise 结果的对象数组。

const promise1 = Promise.resolve(3)
const promise2 = new Promise((resolve, reject) =>
  setTimeout(reject, 100, 'foo')
)
const promises = [promise1, promise2]

Promise.allSettled(promises).then((results) =>
  results.forEach((result) => console.log(result.status))
)

// Expected output:
// "fulfilled"
// "rejected"

那如果不用该方法,如何实现呢? 可以想到的是 Promise.all, 但是这个方法存在短路现象, 即出现错误则立即停止其它异步的执行, 返回该错误。

解决办法:在外部包一层 Promise.then 方法, 使得所有方法都能正常回调, 再加上一个状态作为运行结果区分。

function wrappedPromise(promise) {
  return promise.then(
    (value) => ({ status: 'fulfilled', value }),
    (reason) => ({ status: 'rejected', reason })
  )
}

const promises = [
  Promise.resolve('Success!'),
  Promise.reject('Error occurred!'),
  Promise.resolve('Another success!'),
]

Promise.all(promises.map((p) => wrappedPromise(p))).then((results) => {
  results.forEach((res) => {
    if (res.status === 'fulfilled') {
      console.log('success', res.value)
    } else {
      console.log('error', res.reason)
    }
  })
})
Loading...