一. 构造函数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 函数。