首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

前端ES6中Promise的运行原理第一篇

Promise的作用

它是异步编程的一种方式,它比传统的异步回调和事件更合理也更优雅!

从Promise的使用中能看出什么?

首先我们手写一个常见的使用方式

demo1

从这个demo中就可以看出来,首先需要定义一个Promise的构造函数、then方法以及catch方法。then方法可以传入两个函数作为参数,catch就是then演变而来的(第一个参数传null)。Promise的构造函数有一个函数作为参数,这个函数也有两个参数(resolve,reject)并且它们俩也是函数。

demo2

以上这段代码从使用promise的表面就能看出来。

Promise链式调用

我们把demo1换一种书写的形式

demo3

从上面的代码中可以看出来,Promise采用链式调用,类似于jquery,无论then还是catch肯定都返回一个promise对象,那么p1、p2、p3、p4返回的promise对象是同一个吗?并不是!!!每次调用then方法都会返回一个新的promise对象。

demo4

Promise对象的状态

promise对象存在三种状态

未执行

执行完成,此处又分两种

demo5

Promise链式调用的结果传递

看demo3,除了p1初始化一个promise对象外,p2、p3、p4都各自生成了一个promise对象,每个promise对象除了挂载一个运行状态外,还挂载运行结果、下一个promise对象,以及then中的两个参数函数。

demo6

可以想到只要上一个promise运行完成,就能拿到上一个promise的运行结果和运行状态,就能传给下一级,subscribers会根据上一个promise的运行状态来选择运行fn1还是fn2,然后把上一个promise的运行结果传递给它们其中一个。最后待完成之后,又会通过child寻找下一个child,一层层找下去。

Promise链式调用中出现异常

修改demo3

demo7

我们一般提倡不写then的第二个函数,下面接catch方法,这样看起来更优雅

p1运行后的状态是2,但是p2中的then方法没有第二参数函数,这样的情况是p2的状态和运行结果会被设置为和p1一致,p3也没有第二个参数,它也会跟随p2的状态,直到catch。

demo8

运行catch的时候,结果符合预期没有发生异常,所以呢,这个p4的状态又变成了1,下面的p5肯定也是1,之前的p2、p3中的状态和结果会和它们的上一级保持一致,虽然它们的then方法的第一个参数没有运行。

为什么Promsie中异步的情况下链式也能正常执行

存在异步的情况

看demo1

1、无论是new一个promise对象还是后面执行then和catch方法都是同步的,它们都是在做初始化的工作;

2、其中重要的就是每次运行一个then都会创建一个新的promise对象作为上一个promise对象的child,上一个promise对象作为parent,而child是否挂载到parent上作为它的一个属性取决于创建child的时候parent的状态state还是不是为0,如果parent已经运行完成,状态变成了1或者2,child可以直接拿到parent的结果,那么就不需要把child挂载到parent上,反之需要!

3、当开关->parent->child->child->.....这样的链路建立以后,无论什么时候打开开关,它都会像多米诺骨牌一样向后依次执行,而resolve/reject就是这个开关

为什么Promise中能抓住异常并把异常传递到catch中处理

无论是promise构造函数中参数函数,还是then中的参数函数,它们都是在一个try catch中执行的,catch中会用reject处理

demo9

异步中的异常是抓不住的!

总结

本来想写全的,但是发现越写东西越多,这篇文章就分析到这吧,后面再补充!很多东西讲浅了怕说的不全面,讲深了又怕描述不清楚!

喜欢我的文章就关注我吧,有问题可以发表评论,我们一起学习,共同成长!

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190707A0GXLE00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券