Promise API 实现

73 阅读1分钟

Promise.all

Promise.all = (promises) => {
    return new Promise((resolve,reject) => {
        let result = []
        let count = 0
        if(promises.length === 0) {
            resolve(result) 
            return
        }
        for(let i = 0 ; i < promises.length; i++) {
            //包一层resolve,将非promise参数转成promise
            Promise.resolve(Promises[i]).then(value => {
                result[i] = value
                count += 1
                if(count === promises.length) resolve(result)
            }, reason => {
                reject(reason)
            })
        } 
    })
}

Promise.any

Promise.any = (promises) => {
    return new Promise((resolve,reject) => {
        let reasons = []
        let count = 0
        if (promises.length === 0) {
            reject(new AggregateError(reasons))
        }
        for (let i = 0; i < promises.length; i++) {
            Promise.resolve(promises[i]).then(resolve,reason => {
                reasons[i] = reason
                count++
                if (count === promises.length) reject(AggregateError(reasons))
            })
        } 
    })
}

Promise.race

Promise.race = (promises) => {
    return new Promise((resolve,reject) => {
        for (let promise of promises) {
            Promise.resolve(promise).then(value => {
                resolve(value)
            }, reason => {
                reject(reason)
            })
        }
    }) 
}

Promise.allSettled

Promise.allSettled = (promises) => {
    return new Promise((resolve,reject) => {
        let result = []
        let count = 0
        if (promises.length === 0) {
            resolve(result)
            return
        }
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(value => {
                let obj = {
                    status:'fulfilled',
                    value
                }
                result[i] = obj
                count++
                if (count === promises.length) resolve(result)
            }, reason => {
                let obj = {
                    status:'rejected',
                    reason
                }
                result[i] = obj
                count++
                if (count === promises.length) reject(result)
            })
        }
    })
}

Promise.finally

Promise.prototype.finally = () => {
    return this.then(value => {
        return Promise.resolve(onFinally()).then(() => value)
    }, reason => {
        return Promise.resolve(onFinally()).then(() => {throw reason})
    })
}