ES6中的promise实现原理

729 阅读3分钟

1.ES6中的promise实现原理

1-1:promise的基本含义:

  • 1-1-1. promise是一个类,使用的时候需要new这个类
  • 1-1-2. 需要传入一个executor执行器,默认会被立即调用,参数有两个,一个是resolve,一个是reject
  • 1-1-3. promise有三个状态,一个padding,一个成功态(onfullfield,)一个失败态(onrejected)
  • 1-1-4. new Promise返回的一个实例,这个实例上有.then的方法, then方法有两个回调,一个是成功的回调,一个是失败的回调
  • 1-1-5. 走向失败有两种情况,第一个中情况是走reject,第二种是用户主动抛出异常
  • 1-1-6. 一个promise可以走多次then方法
  • 1-1-7.promise的状态不能从成功便成失败,也不能从失败便成失败,只有pedding的时候才可以更改状态;

1-2:promise的实现原理

const PEDDING = 'pedding' //默认状态是pedding
const FULFULLED = 'fulfilled' //成功之后的状态
const REJECTED = 'reject' //失败之后的状态

function resolvePrimise(x,promise,resolve,reject){
    console.log(promise);
    console.log(x);
    // 1.如果X是一个普通值,直接调用resolve回调并把值抛出去。 
    // 2.如果x也是一个promise,那么应该去采用这个promise的状态选择该调用resolve还是reject
    // 避免循环引用
    if( x === promise )return reject( new TypeError('循环引用') )
    // 判断x是否为promise,promise具备有then的房能调用then就是一个对象,如果不是则直接返回
    if( typeof x === 'object' && x != null ){
        // 是否有then方法,如果取不到抛出异常,则直接抛出rejcet方法
        try {
            let then = x.then;//尝试取then
            if( typeof then === 'function' ){
                then.call( x,(y) => {
                    // 参数y有可能还是一个promise,需要再次解析调用流程
                     resolvePrimise(y,promise2,resolve,reject)
                 },(r) => {
                    reject(r)
                })
            }

        } catch (error) {
            reject(error)
        }
    } else {
        resolve(x)
    }
}

class Promise {
    constructor(executor) {
        // 默认会理解执行executor
        // 有两个参数,一个是onresolve,一个是onreject
        // 定义两个变量。一个是成功的值,一个是失败的值
        // 定义一个状态,默认是pedding
        this.successValue = undefined;
        this.errorValue = undefined;
        this.status = PEDDING
        this.onfulfilledSuccessCallback = []
        this.onrejectedErrorCallback = []
        // promise成功或失败不可逆,所以需要在成功或失败的方法里加一个判断,
        // 只有pedding的时候才可以改变
        let onresolve = (val) => {
            // 拿到用户传入的成功值,并保存起来
            // 并且更改状态为fulfilled
            if (this.status == PEDDING) {
                this.successValue = val;
                this.errorValue = val;
                this.status = FULFULLED;
                this.onfulfilledSuccessCallback.forEach(fn => {
                    fn()
                })
            }
        }
        let onreject = (val) => {
            // 拿到用户传入的失败值,并保存起来
            // 并且更改状态为reject
            if (this.status == PEDDING) {
                this.errorValue = val;
                this.status = REJECTED
                this.onrejectedErrorCallback.forEach(fn => {
                    fn()
                })
            }
        }
        // 用户主动抛异常,也会走onreject方法
        try {
            executor(onresolve, onreject)
        } catch (error) {
            onreject(error)
        }
    }
    // x变量就是上一次then中成功或失败的返回值,这个x的值决定下一次then走成功还是失败
    then(onfulfilled, onrejected) {
        // 在then中返回一个新的promise类
        let promise2 = new Promise((resolve, reject) => {
            // 当用户调用.then方法时,判断当前的状态是fulfilled还是reject
            if (this.status == FULFULLED) {
                try {
                    let x = onfulfilled(this.successValue)
                    // resolvePrimise方法是为了完善如果返回的是一个promise时的处理
                    /**
                     * 1.x
                     * 2.promise2
                     * 3.成功(resolve)
                     * 4.失败(reject)
                     */
                    resolvePrimise(x, promise2, resolve, reject)
                } catch (error) {
                    reject(error)
                }
            }
            if (this.status == REJECTED) {
                try {
                    let x = onrejected(this.val)
                    resolvePrimise(x, promise2, resolve, reject)
                } catch (error) {
                    reject(error)
                }
            }
            // 为了解决异步的问题,有可能当前状态是pedding,需要将当前的成功或失败保存起来
            if (this.status == PEDDING) {
                this.onfulfilledSuccessCallback.push(() => {
                    try {
                        let x = onfulfilled(this.successValue)
                        resolvePrimise(x, promise2, resolve, reject)
                    } catch (error) {
                        reject(error)
                    }
                })
                this.onrejectedErrorCallback.push(() => {
                    try {
                        let x = onrejected(this.errorValue)
                        resolvePrimise(x, promise2, resolve, reject)

                    } catch (error) {
                        reject(error)
                    }
                })
            }
        })
        return promise2
    }
}
module.exports = Promise

如果有理解不对的地方还请指点一下