Promise源码

122 阅读2分钟


const PENDING = 'PENDING';
const RESOLVED = 'RESOLVED';
const REJECTED = 'REJECTED';

//resolvePromise  所有promise都要坚持 bluebird q es6
const resolvePromise = function (promise2, x, resolve, reject) {
    //循环使用自己直接跑出错误
    if (promise2 === x) {//用一个类型错误抛出,结束promise
        return reject(TypeError('chaning cycle deteced for promise #<Promise>'))
    }

    let called = false
    if ((typeof x === 'object' && x !== null) || typeof x === 'function') {
        try {
            //避免反复读取
            let then = x.then
            if (typeof then === 'function') {
                //避免反复读取执行
                then.call(x, y => { //then.call 把this指向x
                    if (called) return
                    called = true
                    resolvePromise(promise2, y, resolve, reject) //递归解析resolve中都promise
                }, e => {
                    if (called) return
                    called = true
                    reject(e)
                })
            } else {
                resolve(x)
            }
        } catch (e) {
            if (called) return
            called = true
            reject(e)
        }
    } else {
        resolve(x)
    }
}
class Promise {
    constructor(executor) {
        this.status = PENDING
        this.value = undefined
        this.reject = undefined
        this.onResolvedCallbacks = [];
        this.onRejectedCallbacks = []
        let resolve = (value) => {//掉这个方法就是成功
            if (value instanceof Promise) {
                value.then(resolve, reject)//递归解析resolve中的promise
            }
            if (status === PENDING) {
                this.status = RESOLVED
                this.value = value
                this.onResolvedCallbacks.forEach(fn => fn())
            }
        }
        let reject = (reject) => { //掉这个方法是失败
            if (status === PENDING) {
                this.status = REJECTED
                this.reject = reject
                this.onRejectedCallbacks.forEach(fn => fn())
            }
        }
        try {
            //执行传入的new promise时传入的回调函数
            executor(resolve, reject)
        } catch (e) {
            //如果错误改变状态 返回错误
            this.status = REJECTED
            this.reject = e
        }

    }
    then(onFulfilled, onRejected) {
        //调then方法时onFullfilled 判断时否时函数,时回调函数就往下执行,不是
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : e => e
        onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err }
        let promise2 = new Promise((resolve, reject) => {
            if (this.status === RESOLVED) {
                setTimeout(() => {
                    try {
                        let x = onFulfilled(this.value)
                        resolvePromise(promise2, x, resolve, reject)
                    } catch (e) {
                        reject(e)
                    }

                })
            } else if (this.status === REJECTED) {
                setTimeout(() => {
                    try {
                        let x = onRejected(this.reject)
                        resolvePromise(promise2, x, resolve, reject)
                    } catch (e) {
                        reject(e)
                    }
                })
            } else if (this.status === PENDING) {
                this.onResolvedCallbacks.push(() => {
                    setTimeout(() => {
                        try {
                            let x = onFulfilled(this.value)
                            resolvePromise(promise2, x, resolve, reject)
                        } catch (e) {
                            reject(e)
                        }
                    })
                })
                this.onResolvedCallbacks.push(() => {
                    setTimeout(() => {
                        try {
                            let x = onRejected(this.reject)
                            resolvePromise(promise2, x, resolve, reject)
                        } catch (e) {
                            reject(e)
                        }
                    })
                })
            }
        })
        return promise2
    }
    catch(errCallback) {
        return this.then(null, errCallback)
    }

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

    static reject(reson) {
        return new Promise((resolve, reject) => {
            reject
        })
    }

}

//promise的延迟对象
Promise.defer = Promise.deferred = function () {
    let dfd = {};
    dfd.promise = new Promise((resolve, reject) => {
        dfd.resolve = resolve
        dfd.reject = reject
    })
    return dfd
}

Promise.prototype.finally = function (callback) {
    return this.then((value) => {
        return Promise.resolve(callback()).then(() => value)
    }, (err) => {
        return Promise.resolve(callback()).then(() => { throw err })
    })
}

const isPromise = function (value) {
    return typeof value.then === 'function'
}

Promise.all = function (promises) {
    return new Promise((resolve, reject) => {
        const arr = []
        let index = 0
        const processData = (key, data) => {
            arr[key] = data
            index++
            if (index === promises.length) {
                resolve(arr)
            }
        }

        for (let i = 0; i < promises.length; i++) {
            let result = promises[i]
            if (isPromise(result)) {
                result.then(data => {
                    processData(i, data)
                }, reject)
            } else {
                processData(i, result)
            }
        }
    })
}

Promise.race = function (promises) {
    return new Promise((resolve, reject) => {
        for (let i = 0; i < promises.length; i++) {
            let result = promises[i]
            if (isPromise(result)) {
                result.then(resolve, reject)
            } else {
                resolve(result)
            }
        }
    })
}


module.exports = Promise