promise执行细节

promise状态: pending、 fulfilled、rejected

pending转换成fulfilled与rejected状态

promise内部分装resolve与rejected方法、类公有属性status、fulfilledFns、rejectedFns、value及公有属性reason

        resolve方法:赋值当前promise成功态(fulfilled)时的value值,如果promise当前状态为pending则改变当前promise状态为fulfilled 同时执行promise原型方法中then方法存储的事件集合fulilledFns 

        如果resolve参数为promise实例 则直接调用此参数的then方法,then方法的参数为当前promise实例中的resolve与reject方法 这样当then方法参数回调被调用之后,成功或失败的返回值则直接反映到外层当前promise中继续resolve的状态处理

        reject方法:大致同resolve方法

        value:会作为then方法的第一个参数回调的参数;此值在resolve()方法中确定赋值方式大致如下图代码:

        reason:会作为then方法的第二个参数回调的参数;此值在resolve()方法中确定赋值方式大致如下图代码

        fulfilledFns: 为then方法第一个参数的回调函数的缓存集合  场景:当一个promise实例状态为pending的时候 实例调用了then方法 这个时候promise中的value或reason还未被赋值 即then方法中的参数回调中的参数还未生成所以then方法中的参数回调不可以立即执行要进行缓存处理  可理解为fulfilledFns.push(then方法的第一个参数回调)

        rejectedFns:同fulfilledFns,rejectedFns.push(then方法的第二个参数回调)

    例:

function resolve(value) {
       if(value instanceof Promise) {
            return value.then(resolve, reject);
       }
       this.status = FULFILLED;
       this.value = value;
       this.fulfilledFns.forEach(cb => cb(this.value));
}
function reject(value) {
       if(value instanceof Promise) {
            return value.then(resolve, reject);
       }
       this.status = REJECTED;
       this.reason = reason;
       this.rejectedFns.forEach(cb => cb(this.value));
}

有几个情况:

情况一:promise实例调用then方法的时候,promise的state状态已经处于fulilled状态或者rejected状态

        Promise.prototype.then方法的内部处理逻辑会判断当前promise实例所属状态是否为此状态如果是的话则根据state状态直接执行then方法所传的参数回调 (fulfilled状态执行第一个参数回调,rejected执行第二个参数回调)

        注意在执行之前则会再次创建并返回新的promise实例 目的是为了处理then方法参数回调的返回值是promise实例的情况  同时也是为了串联调用风格  引出方法resolvePromise

if (this.status === FULFILLED) {
        return newPromise = new Promise((resolve, reject) => {
            setTimeout(() => {
                try{
                    let x = onFulfilled(this.value);
                    resolvePromise(newPromise, x, resolve, reject);
                } catch(e) {
                    reject(e);
                }
            });
        })
    }

    if (this.status === REJECTED) {
        return newPromise = new Promise((resolve, reject) => {
            setTimeout(() => {
                try {
                    let x = onRejected(this.reason);
                    resolvePromise(newPromise, x, resolve, reject);
                } catch(e) {
                    reject(e);
                }
            });
        });
    }

方法resolvePromise:

        如果then方法返回值是一个非promise值(如果是一个包含then方法的对象会特殊处理 立即执行这个then)则会调用newPromise对象的resolve、reject方法将x作为参数存入newPromise的value或者reason中 后面链式调用.then().then()的时候可直接获取此x

        如果方法返回值x依旧是一个promise实例并且状态为非pending的话 则会调用x.then(newPromise的resolve,newPromise的reject)方法,参数为newPromise的resolve与reject方法,直接将值暴露外层。

        如果方法返回值x是一个promise实例并且状态为pending的话 则会调用x.then((y)=>{resolvePromise(newPromise,x,resolve,reject)})运用递归将方法存入fulfilledFns方法集合中等待此promise状态为非pending时执行方法 由于此resolve为newPromise的resolve则链式调用的then方法即newPromise.__proto__.then中参数为x返回的promise中的value 即调用x中的resolve方法赋值的value   x中的resolve触发调用之后会触发newPromise.__proto__.then参数回调 从而获取x中的value实现链式调用

        

function resolvePromise(promise2, x, resolve, reject) {
    if (x instanceof Promise) {
        if (x.status === PENDING) {
            x.then(y => {
                resolvePromise(promise2, y, resolve, reject);
            }, reason => {
                reject(reason);
            });
        } else {
            x.then(resolve, reject);
        }
    } else if (x != null && ((typeof x === 'object') || (typeof x === 'function'))) {
        try {
            resolve(x);
        } catch(e) {
            if(called) return;
            reject(e);
        }
    } else {
        resolve(x);
    }
}

情况二:promise实例调用then方法的时候,promise的state状态依然处于pending状态

        则此then方法的返回值promise会将即将执行的then方法的参数及其他处理逻辑包裹一层回调函数push进入fulfilledFns集合中等待promise状态被resolve或reject方法改变之后调用fulfilled集合执行then方法的参数回调函数并根据then方法的参数回调函数的返回值进一步调用resolvePromise来处理 逻辑同上 例:

        

if (that.status === PENDING) {
        return newPromise = new Promise((resolve, reject) => {
            that.fulfilledFns.push((value) => {
                try {
                    let x = onFulfilled(value);//then(onFulfilled,onRejected)
                    resolvePromise(newPromise, x, resolve, reject);
                } catch(e) {
                    reject(e);
                }
            });
            that.rejectedFns.push((reason) => {
                try {
                    let x = onRejected(reason);
                    resolvePromise(newPromise, x, resolve, reject);
                } catch(e) {
                    reject(e);
                }
            });
        });
    }

说白了promise就是各种回调的组合 以及方法集合的合理存储

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值