Hello everybody。我又来啦,还记得我们上一张实现的内容吗?
上一张我们实现了一个简单的Promise。我们实现了Promise内部的简单流程和then方法,并且实现了Promise的异步调用。但是我们也留下了一些问题。。。
由于今天的代码是基于上一次我们实现的内容,所以不甚了解的小伙伴们可以去看我上一篇文章。。
文章地址:一步一步实现一个符合PromiseA+规范的Promise库(1)
问题一:then方法的链式调用
我们都知道,一个Promise是可以在其中再次返回Promise的(当然也可以返回一个普通的值)。而且呢,返回的Promise或者返回的普通值我们需要去拿到它的值并且回传给我们下一次的then方法中。比如:
当然我们也可以在then方法中返回一个Promise;
所以问题就来了。
问题二:如果在then方法中返回Promise或者普通值的情况,我们需要怎么处理。
so,开搞。
我们先来处理第一个问题,让我们的then方法支持链式调用,并且能接受普通值。
我们先来修改then方法中的对于成功状态(onfulfilled)的判断,因为下面的跟他是相同的道理。
这里我们首先来看定义的Promise2。为什么要定义这样一个变量呢?
我们要知道,如果要实现Promise中then方法的链式调用。当第一个then运行完毕并且把返回值给我们之后,我们也要返回这个值。
我们不禁要问了?一个值怎么怎么会有then方法呢?所以我们要把这个值包装成一个Promise对象给返回出去。
所以说,我们需要使每个状态都返回一个Promise。。说的有点多。我们来测试一下。
我们接着改下面两个状态。
我们来捋一捋。通过测试。
我们看到代码运行了2.496秒,我们的测试结果是正确的;
到这里我们就解决了then方法链式调用并且在then方法中返回一个普通值到下一次then方法的成功状态中。
接下来我们解决第二个问题。我们是需要允许在then方法中返回Promise的。。所以,我们也要处理这种情况。
Let us try to do it
其实很简单,我们需要一个统一的处理函数来进行在then中返回Promise的处理。。
我们先新建一个方法叫做resolvePromise(Promise的决定)
在规范中说道。
什么意思呢,就是说如果Promise2和x指向的是同一个对象,我们这里就要把需要返回的Promise2置为reject并且要返回一个类型错误。看下面的代码
然后我们描述一下细节。。
这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方法,例如:
当然下面的pending状态也是一样的。
到这里我们的Promise已经实现的差不多了。但是还有一个问题。我们思考以下代码;
上面代码用的是ES6的原生的Promise
what?我们可以看到,第一个then方法中并没有任何东西,然而我们第二个then中却拿到了promies中resolve的值。
我们都知道,then方法中有onfulfilled和onreject两个回调函数,所以我们要处理一下这两个回调函数。
我们可以在then方法中处理一下这两个回调。判断一下他们的类型,如果类型是function就代表这两个回调是有东西的。不然呢我们就返回一个默认的匿名函数,这个函数的参数就是上一次Promise返回的值,也就是当我们再次执行onfulfilled或者onrejected的时候就可以直接拿到这个值了。也就完成了我们想要的效果。
现在,我们基本上就实现了一个比较完整地Promise。我们实现了Promise异步调用,在then方法中返回Promise或者值,实现了then方法中可以没有回调函数也能把执行结果传入下一次的then方法中。
当然我们基本清楚了Promise的基本原理,以后我们就可以说我们既会使用又可以实现一个Promise。
当然还有一些小小的问题,就是Promise中有许多方法我们没有实现。例如:
Promise.resolve() . Promise.reject() ..还有.catch()方法 Promise.all()方法等等
在下一篇文章中,我们会一一的去实现这些方法,并且会介绍一下前端开发这些年的异步发展流程
最初的callback->Promise->generator函数->我们现在常用的 async await
好了,就到这里吧。看到这里蛮不容易,谢谢大家。
忘了更新下篇文章地址了。。