一步一步实现一个符合PromiseA+规范的Promise库(2)

Hello everybody。我又来啦,还记得我们上一张实现的内容吗?


一步一步实现一个符合PromiseA+规范的Promise库(2)
文章图片
上一张我们实现了一个简单的Promise。我们实现了Promise内部的简单流程和then方法,并且实现了Promise的异步调用。但是我们也留下了一些问题。。。
由于今天的代码是基于上一次我们实现的内容,所以不甚了解的小伙伴们可以去看我上一篇文章。。
文章地址:一步一步实现一个符合PromiseA+规范的Promise库(1)
问题一:then方法的链式调用
我们都知道,一个Promise是可以在其中再次返回Promise的(当然也可以返回一个普通的值)。而且呢,返回的Promise或者返回的普通值我们需要去拿到它的值并且回传给我们下一次的then方法中。比如:


一步一步实现一个符合PromiseA+规范的Promise库(2)
文章图片
当然我们也可以在then方法中返回一个Promise;


一步一步实现一个符合PromiseA+规范的Promise库(2)
文章图片
所以问题就来了。
问题二:如果在then方法中返回Promise或者普通值的情况,我们需要怎么处理。


so,开搞。 我们先来处理第一个问题,让我们的then方法支持链式调用,并且能接受普通值。
我们先来修改then方法中的对于成功状态(onfulfilled)的判断,因为下面的跟他是相同的道理。


一步一步实现一个符合PromiseA+规范的Promise库(2)
文章图片
这里我们首先来看定义的Promise2。为什么要定义这样一个变量呢?
我们要知道,如果要实现Promise中then方法的链式调用。当第一个then运行完毕并且把返回值给我们之后,我们也要返回这个值。
我们不禁要问了?一个值怎么怎么会有then方法呢?所以我们要把这个值包装成一个Promise对象给返回出去
所以说,我们需要使每个状态都返回一个Promise。。说的有点多。我们来测试一下。


一步一步实现一个符合PromiseA+规范的Promise库(2)
文章图片
我们接着改下面两个状态。


一步一步实现一个符合PromiseA+规范的Promise库(2)
文章图片
我们来捋一捋。通过测试。


一步一步实现一个符合PromiseA+规范的Promise库(2)
文章图片
我们看到代码运行了2.496秒,我们的测试结果是正确的;
到这里我们就解决了then方法链式调用并且在then方法中返回一个普通值到下一次then方法的成功状态中。


一步一步实现一个符合PromiseA+规范的Promise库(2)
文章图片
是不是感觉很爽 接下来我们解决第二个问题。我们是需要允许在then方法中返回Promise的。。所以,我们也要处理这种情况。
Letustry to do it
一步一步实现一个符合PromiseA+规范的Promise库(2)
文章图片
展示一下我深厚的英语功底

其实很简单,我们需要一个统一的处理函数来进行在then中返回Promise的处理。。
我们先新建一个方法叫做resolvePromise(Promise的决定)


一步一步实现一个符合PromiseA+规范的Promise库(2)
文章图片
在规范中说道。


一步一步实现一个符合PromiseA+规范的Promise库(2)
文章图片
什么意思呢,就是说如果Promise2和x指向的是同一个对象,我们这里就要把需要返回的Promise2置为reject并且要返回一个类型错误。看下面的代码


一步一步实现一个符合PromiseA+规范的Promise库(2)
文章图片
额,就是这样 然后我们描述一下细节。。


一步一步实现一个符合PromiseA+规范的Promise库(2)
文章图片
emmmmmmmm...

一步一步实现一个符合PromiseA+规范的Promise库(2)
文章图片
这TM有点细节。。 好了不逗了,我们在代码里面分析的很清楚了。我们来捋一捋思路。
在then方法中是可以返回一个Promise的对吧,然后我们拿到了then方法的执行结果,也就是可能是一个Promise或者是一个普通值(也就是x)。然后我们对这个x进行判断,我们首先要判断这个x是不是一个Promise对吧。
如果不是我们可以直接返回x,如果是的话,我们应该知道,Promise都会有then方法。我们接下来就需要判断这个then方法是不是一个function。如果不是我们就直接返回这个then的值,emmm...他应给就是一个普通值。
如果这个then方法是一个function我们就可以直接去执行他。我们在两个回调中进行操作,如果执行的是onfulfilled则我们进行了关键的一步,就是递归调用我们的resolvePromise方法去看我们的onfulfilled传进来的参数是否还是一个Promise,,就这样一直调用,,直到x或者x.then是一个普通的值为止,然后我们就可以返回这个值,也就是resolve我们最后的值。
当然我们这里加了try{}catch(){}还是为了避免程序运行中的错误。
然后我们就可以把我们之前的状态判断中的resolve替换成我们的resolvePromise方法,例如:


一步一步实现一个符合PromiseA+规范的Promise库(2)
文章图片
当然下面的pending状态也是一样的。


一步一步实现一个符合PromiseA+规范的Promise库(2)
文章图片
到这里我们的Promise已经实现的差不多了。但是还有一个问题。我们思考以下代码;


一步一步实现一个符合PromiseA+规范的Promise库(2)
文章图片
上面代码用的是ES6的原生的Promise
what?我们可以看到,第一个then方法中并没有任何东西,然而我们第二个then中却拿到了promies中resolve的值。
我们都知道,then方法中有onfulfilled和onreject两个回调函数,所以我们要处理一下这两个回调函数。


一步一步实现一个符合PromiseA+规范的Promise库(2)
文章图片
注意onrejected中的default函数返回是用了throw。因为我们要返回到下一次的reject中 我们可以在then方法中处理一下这两个回调。判断一下他们的类型,如果类型是function就代表这两个回调是有东西的。不然呢我们就返回一个默认的匿名函数,这个函数的参数就是上一次Promise返回的值,也就是当我们再次执行onfulfilled或者onrejected的时候就可以直接拿到这个值了。也就完成了我们想要的效果。
现在,我们基本上就实现了一个比较完整地Promise。我们实现了Promise异步调用,在then方法中返回Promise或者值,实现了then方法中可以没有回调函数也能把执行结果传入下一次的then方法中。 当然我们基本清楚了Promise的基本原理,以后我们就可以说我们既会使用又可以实现一个Promise。

一步一步实现一个符合PromiseA+规范的Promise库(2)
文章图片
当然还有一些小小的问题,就是Promise中有许多方法我们没有实现。例如:
Promise.resolve() .Promise.reject()..还有.catch()方法Promise.all()方法等等
在下一篇文章中,我们会一一的去实现这些方法,并且会介绍一下前端开发这些年的异步发展流程
最初的callback->Promise->generator函数->我们现在常用的 async await
好了,就到这里吧。看到这里蛮不容易,谢谢大家。


一步一步实现一个符合PromiseA+规范的Promise库(2)
文章图片
忘了更新下篇文章地址了。。
【一步一步实现一个符合PromiseA+规范的Promise库(2)】更新:一步一步实现一个符合PromiseA+规范的Promise库(3)

    推荐阅读