Skip to content

实现Promise.any

Promise.any() 接收一个由 Promise 所组成的可迭代对象,该方法会返回一个新的 promise,一旦可迭代对象内的任意一个 promise 变成了兑现状态,那么由该方法所返回的 promise 就会变成兑现状态,并且它的兑现值就是可迭代对象内的首先兑现的 promise 的兑现值。如果可迭代对象内的 promise 最终都没有兑现(即所有 promise 都被拒绝了),那么该方法所返回的 promise 就会变成拒绝状态,并且它的拒因会是一个 AggregateError 实例,这是 Error 的子类,用于把单一的错误集合在一起。

警告

Promise.any() 方法依然是实验性的,尚未被所有的浏览器完全支持。它当前处于 TC39 第四阶段草案(Stage 4)

javascript
function MyPromiseAny(args) {
    return new Promise((resolve, reject) => {
        if (!Array.isArray(args)) {
            return reject(new TypeError('arguments must be an array'));
        }
        let argsLen = args.length
        let rejectNum = 0
        for (let p of args) {
            Promise.resolve(p).then(res => {
                resolve(reject)
            }).catch((err) => {
                rejectNum++
                if (rejectNum === argsLen) {
                    reject('AggregateError: All promises were rejected')
                }
            })
        }
    })
}

实现Promise.race

Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个 promise 解决或拒绝,返回的 promise 就会解决或拒绝。

javascript
function MyPromiseRace(args) {
    return new Promise((resolve, reject) => {
        if (!Array.isArray(args)) {
            return reject(new TypeError('arguments must be an array'));
        }
        for (let p of args) {
            Promise.resolve(p).then(res => {
                resolve(res)
            }, err => {
                reject(err)
            })
        }
    })
}

实现Promise.all

Promise.all() 方法接收一个 promiseiterable 类型(注:Array,Map,Set 都属于 ES6iterable 类型)的输入,并且只返回一个Promise实例,那个输入的所有 promiseresolve 回调的结果是一个数组。这个Promiseresolve 回调执行是在所有输入的 promiseresolve 回调都结束,或者输入的 iterable 里没有 promise 了的时候。它的 reject 回调执行时,只要任何一个输入的 promisereject 回调执行或者输入不合法的 promise 就会立即抛出错误,并且 reject 的是第一个抛出的错误信息。

javascript
function MyPromiseAll(args) {
    return new Promise((resolve, reject) => {
        if (!Array.isArray(promises)) {
            return reject(new TypeError('arguments must be an array'));
        }
        let result = []
        let argsLen = args.length
        for (const p of args) {
            Promise.resolve(p).then(res => {
                result.push(res)
                if (argsLen === result.length) {
                    return resolve(result)
                }
            }).catch((err) => {
                return reject(err)
            })
        }
    })
}