Skip to content

手写Promise.all/race/allSettled/any

实现Promise.all方法

Promise.all方法需要满足以下几个条件:

  1. 接收一个Promise数组作为参数
  2. 返回一个新的Promise,该Promise在所有输入的Promise都成功时才会成功,且成功结果为所有Promise成功结果的数组
  3. 如果任何一个输入的Promise失败,那么返回的Promise就会立即失败,且失败原因是第一个失败的Promise的失败原因
代码展示
js
const myAll = (PromiseList) => {
    return new Promise((resolve, reject) => {
        if (!Array.isArray(PromiseList)) {
            reject(new TypeError('Argument must be an array'))
            return
        }
        if (PromiseList.length === 0) {
            resolve([])
            return
        }
        const result = []
        let count = 0
        for (let i = 0; i < PromiseList.length; i++) {
            PromiseList[i].then((res) => {
                result[i] = res
                count++
                if (count == PromiseList.length)
                    resolve(result)
            }).catch((reason) => {
                reject(reason)
            })
        }
    })
}

实现Promise.race方法

Promise.race方法需要满足以下几个条件:

  1. 接收一个Promise数组作为参数
  2. 返回一个新的Promise,该Promise一旦有一个输入的Promise成功或失败,就会立即采用该Promise的状态和结果
代码展示
js
const myRace = (PromiseList) => {
    return new Promise((resolve, reject) => {
        if (!Array.isArray(PromiseList)) {
            reject(new TypeError('Argument must be an array'))
            return
        }
        if (PromiseList.length === 0) {
            resolve([])
            return
        }
        for (let i = 0; i < PromiseList.length; i++) {
            PromiseList[i].then((res) => {
                resolve(res)
            }).catch((reason) => {
                reject(reason)
            })
        }
    })
}

实现Promise.allSettled方法

Promise.allSettled方法需要满足以下几个条件:

  1. 接收一个Promise数组作为参数
  2. 返回一个新的Promise,该Promise在所有输入的Promise都 settled(无论成功或失败)时才会 settled,且成功结果为所有 Promise settled 结果的数组
代码展示
js
const myAllSettled = (PromiseList) => {
    return new Promise((resolve, reject) => {
        if (!Array.isArray(PromiseList)) {
            reject(new TypeError('Argument must be an array'))
            return
        }
        if (PromiseList.length === 0) {
            resolve([])
            return
        }
        const result = []
        let count = 0
        for (let i = 0; i < PromiseList.length; i++) {
            PromiseList[i].then((res) => {
                result[i] = {
                    status: 'fulfilled',
                    value: res
                }
                count++
                if (count == PromiseList.length)
                    resolve(result)
            }).catch((reason) => {
                result[i] = {
                    status: 'rejected',
                    reason
                }
                count++
                if (count == PromiseList.length)
                    resolve(result)
            })
        }
    })
}

实现Promise.any方法

Promise.any方法需要满足以下几个条件:

  1. 接收一个Promise数组作为参数
  2. 返回一个新的Promise,该Promise一旦有一个输入的Promise成功,就会立即采用该Promise的成功结果
  3. 如果所有输入的Promise都失败,那么返回的Promise就会失败,且失败原因是一个 AggregateError 实例,包含所有失败 Promise 的失败原因
代码展示
js
const myAny = (PromiseList) => {
    return new Promise((resolve, reject) => {
        if (!Array.isArray(PromiseList)) {
            reject(new TypeError('Argument must be an array'))
            return
        }
        if (PromiseList.length === 0) {
            resolve([])
            return
        }
        const result = []
        let count = 0
        for (let i = 0; i < PromiseList.length; i++) {
            PromiseList[i].then((res) => {
                resolve(res)
            }).catch((reason) => {
                result[i] = reason
                count++
                if (count == PromiseList.length)
                    reject(result)
            })
        }
    })
}