Skip to content

实现一个 Promise.allsettle

js
// 实现
function isPromise(val) {
  return typeof val.then === 'function' // (123).then => undefined
}

Promise.allSettled = function (promises) {
  return new Promise((resolve, reject) => {
    let arr = []
    let times = 0
    const setData = (index, data) => {
      arr[index] = data
      if (++times === promises.length) {
        resolve(arr)
      }
      console.log('times', times)
    }

    for (let i = 0; i < promises.length; i++) {
      let current = promises[i]
      if (isPromise(current)) {
        current.then(
          (data) => {
            setData(i, { status: 'fulfilled', value: data })
          },
          (err) => {
            setData(i, { status: 'rejected', value: err })
          },
        )
      } else {
        setData(i, { status: 'fulfilled', value: current })
      }
    }
  })
}

// 用法
let fs = require('fs').promises

let getName = fs.readFile('./name.txt', 'utf8') // 读取文件成功
let getAge = fs.readFile('./age.txt', 'utf8')

Promise.allSettled([1, getName, getAge, 2]).then((data) => {
  console.log(data)
})
// 输出结果
/*
    [
    { status: 'fulfilled', value: 1 },
    { status: 'fulfilled', value: 'zf' },
    { status: 'fulfilled', value: '11' },
    { status: 'fulfilled', value: 2 }
    ]
*/

let getName = fs.readFile('./name123.txt', 'utf8') // 读取文件失败
let getAge = fs.readFile('./age.txt', 'utf8')
// 输出结果
/*
    [
    { status: 'fulfilled', value: 1 },
    {
      status: 'rejected',
      value: [Error: ENOENT: no such file or directory, open './name123.txt'] {
        errno: -2,
        code: 'ENOENT',
        syscall: 'open',
        path: './name123.txt'
      }
    },
    { status: 'fulfilled', value: '11' },
    { status: 'fulfilled', value: 2 }
  ]
*/

如有转载或 CV 的请标注本站原文地址