前几篇文章,我们一起聊了Promise的运行原理,结合它的原理,我们再聊一下Promise上的几个静态方法的实现原理!
Promise.resolve和Promise.reject
结合之前说的原理,其实就是Promise.resolve返回的Promise对象作为parent,再去拼接下面then返回的Promise对象。Promise.reject也是一样的道理,这个比较简单,就不展开说了!
Promise.finally
finally静态方法和try catch中的finally一样,作为兜底,最终都会执行,实现也比较简单,看看下面的实现就可以了,也不多说了!
Promise.race
这个静态方法比较有意思,它的语义为竞赛,哪个先完成就使用哪一个!听起来很复杂,其实实现起来很简单!race方法的参数是一个数组,这些数组之间就是竞争关系,竞争谁的状态变化最快!
在运行时,promise会去遍历传进去的数组,并且把每一个数组元素(p1/p2/p3)都包装成一个promise对象,而且它们都被当做p的parent。(注意:p也是一个promise对象)
一旦P1、P2、P3中有一个Promise对象状态发生改变,它就会去改变P的状态,随之结果也会传递给P。当P的状态已经发生改变,那么它就不会再被外部的环境所影响,因此就达到了竞赛的效果。Promise对象的状态有且只能被改变一次。
运用场景:有时我们想要去请求一个图片(new Image.src),但是它没有超时的判断,我们想让它和ajax那样拥有超时截断能力,这时就可以让请求的操作和定时器做一次竞赛!
Promise.all
all也是接受一个数组参数,和race一样,这个方法是所有的参数都产生正向的结果,才会继续向下执行,这个方法的实现稍微有点复杂!我们稍微修改一下上面的demo。
运行时,promise在遍历它们的时候会把它们封装成一个个的promsie对象。
p1、p2、p3当他们各自状态改变时,它们并不会急于去修改p的状态,而是先把计数变量remain加1,再去查看remain的值是否和all中传入的数组长度相同(即保证所有的promise状态都已改变),如果remain==3(在这个例子里面是这样的),就会直接改变P的状态并且把p1、p2、p3运行的结果放在一个数组里面传给P,如果remain!=3,那就继续等待它们所有都完成。
注意:一旦当p1、p2、p3中出现了异常,那么就直接把那个异常给到P,不会再去等待其他promise的状态返回。
总结
这篇文章是关于promsie原理的最后一篇,聊到这里应该百分之七八十的东西都说完了,还有一点点细节其实是很难用通俗易懂的语言描述的,如果说出来,反而会让读者不容易懂。不能仅仅只有自己懂,也要让别人懂看懂,这样的分享才有意义。
喜欢我的文章就关注我吧,有问题可以发表评论,我们一起学习,共同成长!