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

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

clipboard.png

上一张咱们实现了一个简单的Promise。咱们实现了Promise内部的简单流程和then方法,而且实现了Promise的异步调用。可是咱们也留下了一些问题。。。异步

因为今天的代码是基于上一次咱们实现的内容,因此不甚了解的小伙伴们能够去看我上一篇文章。。async

文章地址:一步一步实现一个符合PromiseA+规范的Promise库(1)函数

问题一:then方法的链式调用测试

咱们都知道,一个Promise是能够在其中再次返回Promise的(固然也能够返回一个普通的值)。并且呢,返回的Promise或者返回的普通值咱们须要去拿到它的值而且回传给咱们下一次的then方法中。好比:spa

clipboard.png

固然咱们也能够在then方法中返回一个Promise;3d

clipboard.png

因此问题就来了。对象

问题二:若是在then方法中返回Promise或者普通值的状况,咱们须要怎么处理。blog

so,开搞。递归

咱们先来处理第一个问题,让咱们的then方法支持链式调用,而且能接受普通值。

咱们先来修改then方法中的对于成功状态(onfulfilled)的判断,由于下面的跟他是相同的道理。

clipboard.png

这里咱们首先来看定义的Promise2。为何要定义这样一个变量呢?

咱们要知道,若是要实现Promise中then方法的链式调用。当第一个then运行完毕而且把返回值给咱们以后,咱们也要返回这个值。

咱们不由要问了?一个值怎么怎么会有then方法呢?因此咱们要把这个值包装成一个Promise对象给返回出去。

因此说,咱们须要使每一个状态都返回一个Promise。。说的有点多。咱们来测试一下。

clipboard.png

咱们接着改下面两个状态。

clipboard.png

咱们来捋一捋。经过测试。

clipboard.png

咱们看到代码运行了2.496秒,咱们的测试结果是正确的;

到这里咱们就解决了then方法链式调用而且在then方法中返回一个普通值到下一次then方法的成功状态中。

clipboard.png
是否是感受很爽

接下来咱们解决第二个问题。咱们是须要容许在then方法中返回Promise的。。因此,咱们也要处理这种状况。

Let us try to do it

clipboard.png
展现一下我深厚的英语功底

其实很简单,咱们须要一个统一的处理函数来进行在then中返回Promise的处理。。

咱们先新建一个方法叫作resolvePromise(Promise的决定)

clipboard.png

在规范中说道。

clipboard.png

什么意思呢,就是说若是Promise2和x指向的是同一个对象,咱们这里就要把须要返回的Promise2置为reject而且要返回一个类型错误。看下面的代码

clipboard.png
额,就是这样

而后咱们描述一下细节。。

clipboard.png

clipboard.png

emmmmmmmm...

这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方法,例如:

clipboard.png

固然下面的pending状态也是同样的。

clipboard.png

到这里咱们的Promise已经实现的差很少了。可是还有一个问题。咱们思考如下代码;

clipboard.png

上面代码用的是ES6的原生的Promise

what?咱们能够看到,第一个then方法中并无任何东西,然而咱们第二个then中却拿到了promies中resolve的值。

咱们都知道,then方法中有onfulfilled和onreject两个回调函数,因此咱们要处理一下这两个回调函数。

clipboard.png

注意onrejected中的default函数返回是用了throw。由于咱们要返回到下一次的reject中
咱们能够在then方法中处理一下这两个回调。判断一下他们的类型,若是类型是function就表明这两个回调是有东西的。否则呢咱们就返回一个默认的匿名函数,这个函数的参数就是上一次Promise返回的值,也就是当咱们再次执行onfulfilled或者onrejected的时候就能够直接拿到这个值了。也就完成了咱们想要的效果。

如今,咱们基本上就实现了一个比较完整地Promise。咱们实现了Promise异步调用,在then方法中返回Promise或者值,实现了then方法中能够没有回调函数也能把执行结果传入下一次的then方法中。

固然咱们基本清楚了Promise的基本原理,之后咱们就能够说咱们既会使用又能够实现一个Promise。

clipboard.png

固然还有一些小小的问题,就是Promise中有许多方法咱们没有实现。例如:

Promise.resolve() . Promise.reject() ..还有.catch()方法 Promise.all()方法等等

在下一篇文章中,咱们会一一的去实现这些方法,而且会介绍一下前端开发这些年的异步发展流程

最初的callback->Promise->generator函数->咱们如今经常使用的 async await

好了,就到这里吧。看到这里蛮不容易,谢谢你们。

clipboard.png

相关文章
相关标签/搜索