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

今天我们来自己手写一个符合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方法是如何链式调用的,以及链式调用中的许多坑。。。

好啦,谢谢大家看到这里。感谢。

更新。下一篇文章地址为:一步一步实现一个符合PromiseA+规范的Promise库(2)

再次感谢。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容

  • 本文适用的读者 本文写给有一定Promise使用经验的人,如果你还没有使用过Promise,这篇文章可能不适合你,...
    HZ充电大喵阅读 7,242评论 6 19
  • Promise 对象 Promise 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案——回调函...
    neromous阅读 8,554评论 1 56
  • 前言 本文旨在简单讲解一下javascript中的Promise对象的概念,特性与简单的使用方法。并在文末会附上一...
    _暮雨清秋_阅读 2,146评论 0 3
  • 排版很不友好,抱歉 /* * 实现Promise是根据Promise规范来的:https://promisesap...
    Egde阅读 1,437评论 0 0
  • static :静态变量:只有未定义时才会声明,否则值会累加,获取最近的值操作; 递归函数 进入函数,最后有明确值...
    overisover阅读 359评论 0 0