摘要:今天我们来自己手写一个符合规范的库。是异步编程的一种解决方案,比传统的解决方案回调函数和事件更合理和更强大。我们可以看到,其实就是一个构造函数。所以说我们的数组里存的是一个一个的的回调函数,也就是一个一个。
今天我们来自己手写一个符合PromiseA+规范的Promise库。大家是不是很激动呢??
才没有。。
我们都知道。在现在的前端开发中,Promise这个东西基本上所有的开发中都会用到。
那必然有些萌新就会问了,Promise到底是个什么东西呢。
按照规范来说。Promise是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。
通俗来讲。。这个东西就是为了解决我们平常的回调函数,避免回调地狱的一种解决方案。所以说这个东西大家不仅要会用哦,还应该知道他的一些原理。so,我们一起来实现下吧。
接下来我们先看一个简单的Promise。
这个就是es6标准中的Promise。我们可以看到,其实Promise就是一个构造函数。
这个构造函数中只有一个参数。这个参数在Promise/A+规范中被称为executor(执行者..我觉得叫执行器蛮好)。
因为这个执行器是为了执行后面的resolve(决定)和reject(拒绝)方法。呃...其实你可以把resolve看作是成功,把reject看做失败。
当然了我们还可以根据自己定义的规则来进行Promise中resolve和reject的调用,不过这是用法,我们这里就当大家会用了。。
然后我们可以看到,在构造函数的实例p中还有一个then方法。这里我们就要想了,既然是构造函数的实例上哪必然这个函数是挂在到这个构造函数的原型上。
还有很重要的一点就是我们可以想一下,在Promise中这个Promise的当前状态是一个问题。在A+规范中规定:一个Promise只有三种状态,我们看图
什么意思呢。。
大致的意思就是说,一个Promise有且仅有(pending->等待,fulfilled->已执行,rejected->已拒绝)这三种状态中的一种(ps:我曾经看到过一个词->悬而未决用来形容pending也不错 :)。
我们知道了这些,接下来我们就来手动实现一个简单的。
继续。。。。
这里我们要说一下,貌似刚才忘说了。。。
我们通过这张图来看一下,当目前的状态为pending时。我们可以将pending状态改变为fulfilled或者rejected中的一种。然而我们要记住,之前已经提到过Promise的状态必须是三种之一。而且,如果一旦成功就不能失败,一旦失败就不能成功。
接下来我们依据上面状态的描述来继续、、、
这里当我们调用resolve和reject的时候我们需要做出状态判断,只有是pending状态的时候才可以改变状态为其他两种的任意一种,如果不是:例如
我们处理完了resolve和reject内置的逻辑,这里有一个问题。在开发中,当Promise的执行遇到错误时,会直接变成rejected状态,大家应该都知道,也就是下面的处理。
我们在Promise的执行过程中如果捕获到异常,就可以直接调用reject来结束Promise。
接下来我们看then方法。
这样我们就实现了一个简单的Promise(才没有。。。这才哪到哪),我们来试下效果吧。
别忘了导出我们的Promise。。
我们看到下面的输出结果,哇!!好激动有没有(才没有激动),我也实现了一个Promise!
但是!有一个问题,我们是不是弄丢了一个状态???
what??哪个??仔细想一下好像是‘pending’丢掉了。。
so?那咋办。
有人可能会说了,不是出了成功就是失败吗,为什么会有等待状态呢,我们来思考一下下面的代码。
话说Promise应该都是支持异步的吧?就像上面的代码,异步执行resolve的时候我们是不是已经吧值给弄丢了?
并且我们想一下,弄丢这个值得一段时间是不是就是等待态也就是‘pending’的时候。。
所以,我们要怎么处理这个pending呢?
我们想一下,在executor中的resolve和reject是不是都会吧我们传入的值,传到then方法的onfulfilled和onrejected中?另外,我们在then方法中做了对目前Promise的状态的判断。
所以我们在then方法中去处理‘pending’状态。
怎么去处理呢?我们可以在Promise中挂载两个数组。
为什么?这两个数组的作用是为了记录pending状态下的onfulfilled和onreject函数。我们来看then中的代码。
我们可以看到在pending状态下,这两个数组分别记录了各自对应的then的回调函数,并且保存起来。
我们来捋一捋思路。
所以说我们的数组里存的是一个一个的then的回调函数,也就是一个一个function。
所以我们要在resolve和reject方法触发的时候,去便利我们的数组并且执行其中的方法,并且呢还要把我们成功的原因(self.value)和失败的原因(self.reason)放到我们的回调方法中去。说了这么多有点绕。。上代码
这样就解决了异步的问题。我们再来测试一下。
代码刚开始运行。
2秒后。。。
这时我们就拿到了异步的值,是不是很开心!(有点,嘿嘿)
再看一下我们写的全部的代码:
到这里我们简单了解了Promise的一小部分原理,并且实现了一个非常简单的Promise。今天就先写到这里,在下一章中我们会继续了解Promise中的then方法是如何链式调用的,以及链式调用中的许多坑。。。
好啦,谢谢大家看到这里。感谢。
再次感谢。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/93584.html
摘要:我们都知道,方法中有和两个回调函数,所以我们要处理一下这两个回调函数。我们实现了异步调用,在方法中返回或者值,实现了方法中可以没有回调函数也能把执行结果传入下一次的方法中。 Hello everybody。我又来啦,还记得我们上一张实现的内容吗? showImg(https://segmentfault.com/img/bV6UaU?w=102&h=95); 上一张我们实现了一个简单的...
摘要:简单实现前言你可能知道,的任务执行的模式有两种同步和异步。你已经实现了方法方法是一个很好用的方法。感兴趣的朋友可以自行去研究哈附上代码完整的实现个人博客链接 Promise 简单实现 前言 你可能知道,javascript 的任务执行的模式有两种:同步和异步。 异步模式非常重要,在浏览器端,耗时很长的操作(例如 ajax 请求)都应该异步执行,避免浏览器失去响应。 在异步模式编程中,我...
摘要:不同的的实现需要可以相互调用,搞清楚了标准之后,开始动手吧构造函数产生一个对象有很多种方法,构造函数是看起来最面向对象的一种,而且原生实现也是使用的构造函数,因此我也决定使用构造函数的方法。 -- What i cant create, i dont understant 前言 实现Promise的目的是为了深入的理解Promies,以在项目中游刃有余的使用它。完整的代码见gitHub...
摘要:以上代码,可以完美通过所有用例。在的函数中,为何需要这个同样是因为规范中明确表示因此我们需要这样的来确保只会执行一次。其他情况,直接返回以该值为成功状态的对象。 Promise是前端面试中的高频问题,我作为面试官的时候,问Promise的概率超过90%,据我所知,大多数公司,都会问一些关于Promise的问题。如果你能根据PromiseA+的规范,写出符合规范的源码,那么我想,对于面试...
摘要:嗝首先,我们通过字面可以看出来是一种解决方案,而且还有两种传统的解决方案回调函数和事件,,那么我们就来先聊聊这两种方案。 前言 虽然今年已经18年,但是今天还是要继续聊聊ES6的东西,ES6已经过去几年,可是我们对于ES6的语法究竟是掌握了什么程度,是了解?会用?还是精通?相信大家和我一样都对自己有着一个提升的心,对于新玩具可不能仅仅了解,对于其中的思想才是最吸引人的,所以接下来会通过...
阅读 3115·2023-04-25 15:02
阅读 2789·2021-11-23 09:51
阅读 2029·2021-09-27 13:47
阅读 1984·2021-09-13 10:33
阅读 954·2019-08-30 15:54
阅读 2640·2019-08-30 15:53
阅读 2853·2019-08-29 13:58
阅读 881·2019-08-29 13:54