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

250

日常先打个招呼。。

clipboard.png

今天我们就来完整的实现之前还留有一些小的方法没实现的Promise。。

回顾:一步一步实现一个符合PromiseA+规范的Promise库(1)

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

我们都知道,Promise中的常用方法有then、catch、Promise.resolve、Promise.reject、Promise.all、Promise.race这些常用方法,接下来我们就一一来实现它们。

先来实现.catch方法。

我们来看以下代码

clipboard.png

我们这里使用的是es6原生的Promise,看到在catch拿到了reject的结果。而且我们看到,在then方法中只有onfulfilled一个回掉函数。

而且,catch方法是支持链式调用的,so。。我们需要把这个方法挂载到我们的Promise上。

clipboard.png

这样我们就实现了Promise中的catch方法,是不是很简单。

可以从之前的测试中看到,.catch方法中的参数只有一个回掉函数,这个回掉函数中有一个参数。我们不难看出来,不管怎样,这个catch方法拿到的总是我们程序onrejected状态下的值。所以我们return一个then方法而且只给这个then方法onrejected回调。then方法中onfulfilled状态我们传了一个null,为什么?其实我们前面有讲到过,请参考我上一篇文章: 一步一步实现一个符合PromiseA+规范的Promise库(2)中的onfulfilled和onrejected默认值的问题。这里我们就不再赘述了。

我们再来看看Promose.resolve和Promise.reject这两个方法。

clipboard.png

额。。其实这两个方法也就是分别返回一个成功和失败的Promise。这两个方法作为静态方法直接挂在到Promise上即可。

接下来我们实现Promise.all方法。

我们知道Promise.all这个方法是处理多个Promise组成的数组并且返回一个Promise,当全部的Promise处理完毕后在我们下次调用then方法时将这个处理结果的数组返回。我们看下下面的代码。

clipboard.png
Promise.all用法

所以我们可以根据这个原理,来实现我们的Promise.all方法。

我们来看以下代码。

clipboard.png

额。。我觉得已经蛮清楚了,再捋一捋。

拿到参数Promise数组->遍历执行(调用其then方法)->存放到返回数组中->判断执行是否完毕(完毕:返回我们的数组)。

clipboard.png

今天有些晚了,就先实现这几个吧。race方法等明天或者有空吧。然后我们再来分享下javascript的异步发展流程。。

最初的callback->Promise->generator函数->我们现在常用的 async await

就酱:)

clipboard.png

更新

race方法的实现。

Promise.race这个方法很有意思。。这个方法也是跟all方法一样接受一个Promise组成的数组,但是这些个Promise只要有一个成功了,我们的race方法也就执行完毕了,并且返回Promise的执行结果。我们先来看下用法。

clipboard.png

我们看到这里race方法中有一个Promise数组,不过只返回了一个结果。并且这个race方法也返回了一个Promise,因为我们在接下来的then方法中拿到了之前的执行结果。so。我们来实现下。

clipboard.png

我们可以看到,在循环中我们直接调用了传进来的那些Promise,然后当成功时会直接调用我们返回的Promise的resolve方法把执行的结果返回出去。

到这里我们基本上就实现了一个比较完整的Promise,当然这个Promise还相对简单。不过我们也蛮不错了。

clipboard.png

接下来我们看一下js的异步发展流程.

我们都知道以前比如说我们在处理异步的时候通常会有这样的代码。

回调函数

如果{

    我是说{

            能不能{

                        干一件事{

                         }

            }

    }

}

丑的一批。。

。。其实也还好,主要是还蛮好看的。但是如果我们异步做的多了,回调地狱自然不可避免。所以Promise应运而生。

我们再来看下Promise

一般的代码是这样

Promise.resolve().then().then()......

then多了也不咋好看。。而且一个then中两个回调,再返回Promise。。EMMMMM。。

然后出现的就是我们的generator函数。

generator

clipboard.png

如果用过generator函数的小伙伴们应该知道。generator可以在执行过程中多次返回,所以它看上去就像一个可以记住执行状态的函数,generator函数通常配合Promise和tj写的co库来使用。由于generator函数会产生一个执行器,我们要使用这个执行器的next方法来执行我们的异步方法去得到我们想要的值。

如果有些小伙伴还不明白generator的工作方式,可以去看一下他的使用方法。->Generator 函数的含义与用法

co库可以帮助我们不去管执行器中的next方法,返回一个Promise并且把执行结果放到返回的Promise的then方法中。

我们可以自己实现一个co库,其实也是很简单的一个方法。

clipboard.png

我们看一下测试结果

clipboard.png

发现依旧是没有问题的。这样我们就写了一个简单的co库来帮助我们使用generator函数。

最后一个就是我们的async和await。

async-await

clipboard.png

我们可以看到,async和await,使用起来跟generator函数类似,其实呢,async和await就是generator和yield的一种语法糖,

当然这个语法糖的实现比较复杂,我们如果有时间的话还会跟大家一起实现一下。我们这里先看看他的用法。

我们可以看到,async方法一样的返回了一个Promise,并且相当于自动执行了generator中的next方法,使得我们不必再耗费精力去处理执行器,在开发中使我们的开发体验变好了许多。。毕竟代码还是简洁明了好一点。。。

clipboard.png

好了,一路走来我们也算比较完整的了解了Promise的实现原理,我们也算是完成了一个符合Promise/A+规范的Promise库。然后我们还了解了js近些年来的异步发展,有没有觉得自己很棒呢。。(反正我是觉得我们蛮厉害)

最后,希望大家不管是生活还是学习和工作中都可以更好。再次感谢大家可以看到这里,谢谢。

就酱,Bye~

clipboard.png