模拟原生的promise

class Promise {
    static resolve(data) {
        if (data instanceof Promise) {
            return data
        }
        return new Promise((resolve) => {
            resolve(data)
        })
    }

    static reject(data) {
        if (data instanceof Promise) {
            return data
        }
        return new Promise((resolve, reject) => {
            reject(data)
        })
    }

    static all(promiseObjs) {
        return new Promise((resolve, reject) => {
            let array = []
            let count = 0
            for (const promiseObj of promiseObjs) {
                promiseObj.then(value => {
                    array.push(value)
                    count++
                    if (count === promiseObjs.length){
                        resolve(array)
                    }
                }).catch(reason => {
                    reject(reason)
                })
            }
        })
    }

    static race(promiseObjs){
        return new Promise((resolve, reject) => {
            for (const promiseObj of promiseObjs) {
                promiseObj.then(value => {
                    resolve(value)
                }).catch(reason => {
                    reject(reason)
                })
            }
        })
    }

    resolve(data) {
        if (this.PromiseState !== 'pending') return
        this.PromiseState = 'fulfilled'
        this.PromiseResult = data
        // 执行保存的回调
        const fulfills = this.callbacks.fulfilled
        const length = fulfills.length

        for (let i = 0; i < length; i++) {
            setTimeout(()=> {
                this.executeCallback(fulfills.shift(), [this.PromiseResult], 'fulfilled')
            })
        }
    }

    reject(data) {
        if (this.PromiseState !== 'pending') return
        this.PromiseState = 'rejected'
        this.PromiseResult = data
        // 执行保存的回调
        const rejects = this.callbacks.rejected
        const length = rejects.length
        for (let i = 0; i < length; i++) {
            setTimeout(()=> {
                this.executeCallback(rejects.shift(), [this.PromiseResult], 'rejected')
            })
        }
    }

    constructor(executor) {
        if (typeof (executor) !== 'function') {
            throw TypeError(`Promise resolver ${executor} is not a function`)
        }
        this.PromiseState = 'pending'
        this.PromiseResult = undefined

        // 保存异步修改状态时的回调函数
        this.callbacks = {fulfilled: [], rejected: []}
        // 绑定函数在外部执行时的this指向
        let resolve = this.resolve.bind(this)
        let reject = this.reject.bind(this)
        this.executeCallback(executor, [resolve, reject], 'pending')
    }

    then(onResolved, onRejected) {
        if (this.PromiseState === 'fulfilled') {
            setTimeout(()=>{
                this.executeCallback(onResolved, [this.PromiseResult], this.PromiseState)
            })

        }
        if (this.PromiseState === 'rejected') {
            setTimeout(()=>{
                this.executeCallback(onRejected, [this.PromiseResult], this.PromiseState)
            })
        }
        if (this.PromiseState === 'pending') {
            this.callbacks.fulfilled.push(onResolved)
            this.callbacks.rejected.push(onRejected)
        }
        return this
    }

    catch(onRejected) {
        if (this.PromiseState === 'pending') {
            this.callbacks.rejected.push(onRejected)
        }
        if (this.PromiseState === 'rejected') {
            //模拟真Promise的异步执行
            setTimeout(()=>{
                this.executeCallback(onRejected, [this.PromiseResult], this.PromiseState)
            })
        }
        return this
    }

    executeCallback(func, arg, state) {
        if (typeof (func) !== 'function') {
            return
        }

        if (state === 'pending') {
            try {
                func(...arg)
            } catch (e) {
                this.reject(e)
            }
        }
        if (state === 'fulfilled' || state === 'rejected') {
            try {
                const rest = func(...arg)
                // 如果返回的是一个promise则让this里面的属性改为新的promise对象
                // 如果返回的是非promise对象则直接执行resolve
                if (rest instanceof Promise) {
                    this.PromiseState = rest.PromiseState
                    this.PromiseResult = rest.PromiseResult
                    this.callbacks = rest.callbacks
                } else {
                    this.PromiseResult = rest
                }
            } catch (e) {
                // 先改状态为pending才能执行reject,即:强制设置为rejected
                this.PromiseState = 'pending'
                this.reject(e)
            }
        }
    }
}


(function init(window) {
    window.Promise = Promise
}(window))

原文地址:https://www.cnblogs.com/xiasir/p/15112380.html