前端promise-polyfill关键源码解析

,声明:该源码来自GitHub - taylorhakes/promise-polyfill: Lightweight ES6 Promise polyfill for the browser and node. A+ Compliant

一. 构造函数Promise

         注意:_state 这里面有三种状态与正式的Promise有点差入 0,1, 2,3(3 主要标记_value值为promise的情况)

      1. 初始化状态_state = 0, 当前值_value = undefined,  内部延迟操作数组_deferreds

      2. 调用doResolve,主要是执行构造函数传入的执行函数

二. doResolve 函数

     

1.调用执行函数,传入的两个闭包函数,也就是执行函数接收的resolve,和reject 俩函数,关键是定义了一个开关参数done,防止重复调用,这个done在处理 Promise.all, Promise.race 等并发操作时,很管用

2. 接收的 resolve和reject函数,里面各自调用 pomise 内部的函数,resolve和reject

三 . resolve函数

接收两个参数,一个是promise实例,一个是value值,根据value值的类型,主要看以上两种操作,

1. value值为promise的情况,此时标记状态为3,而不是1,并修改_value,再调用finale函数;

2. value值为常规值情况,状态改为1(即完成状态),修改_value,调用finale函数。

四. finale函数

很简单,遍历调用延迟的操作handle函数

五. handle函数

此方法比较关键做了几件事

1. 根据传入的promise状态,如果是3(即在resolve中标记的),即需要将当前promise替换成_value中的promise,这样就可以让传入的promise和后续的then操作联系起来。

2. 根据传入的promise状态,如果是0,即pendding状态,只是将操作存入_deferreds中,并没有执行回调,也是为什么promise在resolve之前,调用.then 方法,只是收集操作,不执行

3. 调用Promise._immediateFn 方法,这个_immediateFn 是将操作放进 异步了,也是为什么promise是异步的原因,并且里面根据状态,决定调用哪个回调函数,如果是1,则取onFulfilled,2则为onRejected,其中deferred是表示一个操作对象记录了onFulfilled,onRejected回调函数,如果两者都为null,则调用内部resolve和reject函数,意味着该promise调用链结束了

4. 回调不为null情况需要,需要调用回调计算返回值

5. 最后还要继续调用resolve,并将新计算的值传下去,这也是为啥promise链式调用的原因,因为从以上代码可以看到,resolve--finale--handle--resolve 这样一个循环的调用关系

猜想:从这里我们也可以看到,想要promise调用链结束,除了自己调用完毕,还可以让中间某个回调方法返回一个_state = 0的promise,可以终止调用链

六. reject 函数

很简单,修改状态,调用finale

七. Handler 构造函数

    

主要用于在调用then方法时,存储onFulfilled、onRejected、以及新建的promise对象

八. Promise.prototype.then 方法

 

1. 新建一个Handler对象,将onFulfilled, onRejected, 新建的promise对象,存起来

2. 调用handle函数,将当前promise,以及Handler对象传入(可以回到上面看handle函数),收集 then方法的回调操作

3. 返回这个新的promise,表明形如:.then().then().then() 的操作,实际上最后都是在不同的promise上完成then的回调操作的

九. Promise.prototype['catch'] 方法

    

   很简单,就是调用then方法

十. Promise.all 方法

     

1. 返回一个new Promise

2. 定义了一个参数,记录已经调用的次数,当调用次数为数组长度时,就resolve,还定义了一个存放值的数组

3. 定义了一个res闭包函数,其中根据数组中的数据类型,如果是promise则调用then方法,第二个参数,里面函数递归调用res,保证了该promise回调可能继续返回promise的情况,第三个参数传入的是reject,这也是为什么其中一个promise被拒绝,Promise.all 就结束了;如果数据类型是常规值,则直接将值存入数组,

4. 根据传入的数组循环调用res函数

十二. Promise.race 方法

1. 返回一个new Promise

2. 循环调用 Promise.resolve 方法,并接着调用了各自的then方法,并传入resolve,reject,这也是为啥其中一个promise如果完成,则Promise.race 也完成。原因是 resolve和reject 方法中都有一个done参数控制,可以回顾上面的doResolve 函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值