理解 Promise.all 和 Promise.race 的实现
Promise.all
首先我们从一个正常的例子来看拆解一下 Promise.all
拆解Promise.all
- 我们能知道
all
方法接受一个数组作为参数,具体来说应该是具有Iterator
接口的数据。 - 根据
Promise.all
的特性还能知道,Promise.all()
方法用于将多个Promise
实例,包装
成一个新的Promise
实例。言外之意,如果不是 Promise 就会先调用Promise.resolve
方法,将参数转为Promise
实例,再进一步处理。 - 如果参数实例的状态
全部
变成fulfilled
,结果的状态才会变成fulfilled
,此时各个参数的返回值组成一个数组,传递给结果的then
的回调函数。 - 参数实例中有一个被
rejected
,结果的状态就变成rejected
,此时第一个被reject
的实例的返回值,结果会传递给catch
的回调函数。
我们根据上述的拆解,来进行一下代码的实现:
1 |
|
我们使用测试用例验证一下这个方法能不能用,首先模拟一个延迟函数,delay
,然后再定义两个方法 delay1,delay2
。
1 |
|
1 |
|
调用,按照预期的话应该是打印出来两个数据。
1 |
|
最后我们能发现确实已经可以返回两个延迟函数中的数据。
Promise.race
还是根据其特性来实现,首先 race
的方法和 all
的基础性都是一样的,接受的参数以及类别等,其用法是多个实例中有一个实例率先改变状态,总结果的状态就跟着改变。那个率先改变的 Promise
实例的返回值,就传递给结果集的回调函数。
拆解Promise.race
- 首先基本和
all
的类似,然后由其特性可知,其实内部实现应该是谁先完成就谁返回,也就是循环体内部只要有一个成功执行完毕就可以resolve
。
我们来看一下具体实现:
1 |
|
race
最常见的一个场景就是,如果页面里有需要请求的接口,但是接口耗时如果比较长,这个时候可以利用 race
配合 delay
函数做一个兜底,发请求的同时开一个多少 ms
的定时器,如果定时器结束之前接口还没有响应的话则中断请求立即返回,而不至于接口一直处于 pedding
挂起状态。那我们可以根据这个例子验证一下 race
是否可以用。
我们这次修改一下两个延迟函数,
1 |
|
按照预期的话,data
的打印应该是延迟比较小的那个,因为先执行完成先返回了。
1 |
|
由此可见我们的 race
通过用例验证也是可行的。
至此两个比较常用的 promise
的方法我们就实现了,其实很多东西从使用的角度上来看,内部实现原理大概都是能比较清楚的,所以我们就应该注意更多的细节,例如边界条件、类型包装、代码执行的位置等。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!