手写Promise(原生Promise剖析五 - - resolve,reject等方法封装)

前言:在此之前,我们以及陆续封装好了Promise、then、all,这些方法,并且以及讲解了其中的机制,和封装的过程,现在,我们就把剩下的较为简单的方法过一遍。

1. race()

这个方法类似于all方法,传入的参数也是一个有Promise组成的数组,但是它的结果分析起来就相对简单很多,不用过多的考虑,其返回的值也是一个Promise对象,既然返回的是一个Promise对象,那么就存在链式调用,那么就需要进行二次封装,内部就需要调用then方法,它的结果机制是这样的:返回的是一个Promise对象,其对象的值,为传入的Promises中第一个Promise执行后的值,其状态也为该Promise的状态。是不是比all方法简单多了,这样的话我们封装的到结果就为:

// 添加 race 方法
Promise.race = function(promises) {
    return new Promise((resolve , reject) => {
        for(let i = 0 ; i < promises.length ; i++) {
            promises[i].then(v => {
                resolve(v)
            } , r => {
                reject(r)
            })
        }
    })
}

接下来的两种方法也较为简单(resolve() 、reject() ),但是也关系到一点点关键性问题,类似于之前我们讲解race方法,其实是差不多的。

2. resolve()

该方法的返回值和也是一个Promise对象,其返回的结果需要根据传入的值进行区分

(1):传入的为非Promise对象的值,最终方法返回的结果为一个成功状态的Promise,其值为传入的值

(2):传入的为Promise对象,最终方法返回的结果需根据传入的这个Promise对象的执行结果进行判断,和传入的Promise的执行保持一致,传入的为失败,方法返回的就是失败的Promise,传入的为成功,返回的就是成功的Promise,值都是传入的Promise的值

(3):抛出异常,由then方法捕获

这样我们就得到:

// 添加 resolve 方法
Promise.resolve = function(value) {
    return new Promise((resolve , reject) => {
        if(value instanceof Promise) {
            value.then(v => {
                resolve(v)
            } , r => {
                reject(r)
            })
        } else {
            // 传入的参数不是一个promise对象,直接修改状态为成功,值为传入的值
            resolve(value)
        }
    })
}

3. reject()

这里大家可能会想到和resolve方法一样,其实不然,reject方法因为返回方法虽然也是一个Promise对象,但是他不存在链式调用,所以就不需要二次封装,也自然就不需要做过多的判断:

// 添加 reject 方法
Promise.reject = function (reason) {
    return new Promise((resolve, reject) => {
        reject(reason)
    })
}

以上就是剩下的三种方法的封装了。

接下来我们再次进行一个then方法的小优化,我们先来看看一个场景,现在我们封装的then方法和官方库的区别:

场景:

        let p1 = new Promise((resolve , rejeve) => {
            resolve("OK")
            console.log(111)
        })

        p1.then(value => {
            console.log(222)
        },reason => {

        })

        console.log(333)

官方结果:

我们封装的结果:

 结果很明显,这是为什么呢,哎,这就要会到原来的主题,异步调用,我们仔细分析这段代码,官方库中,先执行了Promise里面那段代码,输出了111并且调用了成功的回调对吧,代码往下走,因为是异步调用,所以代码会先走下方同步调用输出333,最后异步执行p1.then()方法执行成功的回调,最后输出222。而我们的呢,并没有进行这个细节的改动,核心的代码是这:

// 判断当前实例对象的Promise状态 依据状态调用相应的函数
if (this.PromiseState === "fulfilled" || this.PromiseState === "resolved") {
     callback(onResolved)
}
if (this.PromiseState === "rejected") {
     callback(onRejected)
}

我们是直接同步执行的,所以我们得把这段改成异步调用的额,很简单,加一个定时器即可了,就像这样(因为定时器就是异步调用的,我们不需要定义异步调用的时间,为空即可):

// 判断当前实例对象的Promise状态 依据状态调用相应的函数
if (this.PromiseState === "fulfilled" || this.PromiseState === "resolved") {
      setTimeout(() => {
          callback(onResolved)
      })
}
if (this.PromiseState === "rejected") {
      setTimeout(() => {
          callback(onRejected)
      })
}

 再次调试看结果:

这样我们就优化好了。

至此,我们的手写Promise的已经完全结束了,之后我会给出一个完整的Promise和类封装的Promise源码,还会列举出一些Promise的关键性问题,也是使用Promise一些的关键问题,封装的过程中也都提到了,之后会做一个汇总,尽请期待

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青灯夜游/

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值