资讯专栏INFORMATION COLUMN

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

jsliang / 543人阅读

摘要:我们都知道,方法中有和两个回调函数,所以我们要处理一下这两个回调函数。我们实现了异步调用,在方法中返回或者值,实现了方法中可以没有回调函数也能把执行结果传入下一次的方法中。

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并且要返回一个类型错误。看下面的代码


额,就是这样

然后我们描述一下细节。。

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

当然下面的pending状态也是一样的。

到这里我们的Promise已经实现的差不多了。但是还有一个问题。我们思考以下代码;

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

what?我们可以看到,第一个then方法中并没有任何东西,然而我们第二个then中却拿到了promies中resolve的值。

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

注意onrejected中的default函数返回是用了throw。因为我们要返回到下一次的reject中
我们可以在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

好了,就到这里吧。看到这里蛮不容易,谢谢大家。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/93732.html

相关文章

  • 步一实现一个符合PromiseA+规范Promise(1)

    摘要:今天我们来自己手写一个符合规范的库。是异步编程的一种解决方案,比传统的解决方案回调函数和事件更合理和更强大。我们可以看到,其实就是一个构造函数。所以说我们的数组里存的是一个一个的的回调函数,也就是一个一个。 今天我们来自己手写一个符合PromiseA+规范的Promise库。大家是不是很激动呢?? showImg(https://segmentfault.com/img/bV6t4Z?...

    joyvw 评论0 收藏0
  • Promise 简单实现

    摘要:简单实现前言你可能知道,的任务执行的模式有两种同步和异步。你已经实现了方法方法是一个很好用的方法。感兴趣的朋友可以自行去研究哈附上代码完整的实现个人博客链接 Promise 简单实现 前言 你可能知道,javascript 的任务执行的模式有两种:同步和异步。 异步模式非常重要,在浏览器端,耗时很长的操作(例如 ajax 请求)都应该异步执行,避免浏览器失去响应。 在异步模式编程中,我...

    dayday_up 评论0 收藏0
  • 实现一个符合标准Promise

    摘要:不同的的实现需要可以相互调用,搞清楚了标准之后,开始动手吧构造函数产生一个对象有很多种方法,构造函数是看起来最面向对象的一种,而且原生实现也是使用的构造函数,因此我也决定使用构造函数的方法。 -- What i cant create, i dont understant 前言 实现Promise的目的是为了深入的理解Promies,以在项目中游刃有余的使用它。完整的代码见gitHub...

    yuanzhanghu 评论0 收藏0
  • Promise源码实现(完美符合Promise/A+规范

    摘要:以上代码,可以完美通过所有用例。在的函数中,为何需要这个同样是因为规范中明确表示因此我们需要这样的来确保只会执行一次。其他情况,直接返回以该值为成功状态的对象。 Promise是前端面试中的高频问题,我作为面试官的时候,问Promise的概率超过90%,据我所知,大多数公司,都会问一些关于Promise的问题。如果你能根据PromiseA+的规范,写出符合规范的源码,那么我想,对于面试...

    gaomysion 评论0 收藏0
  • 啥?喝着阔落吃着西瓜就把Promise手写出来了???

    摘要:嗝首先,我们通过字面可以看出来是一种解决方案,而且还有两种传统的解决方案回调函数和事件,,那么我们就来先聊聊这两种方案。 前言 虽然今年已经18年,但是今天还是要继续聊聊ES6的东西,ES6已经过去几年,可是我们对于ES6的语法究竟是掌握了什么程度,是了解?会用?还是精通?相信大家和我一样都对自己有着一个提升的心,对于新玩具可不能仅仅了解,对于其中的思想才是最吸引人的,所以接下来会通过...

    idisfkj 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<