Promise.all() Promise.race()及其实现

6 篇文章 0 订阅
Promise.all()

Promise.all()是什么? 我们先来回顾一下它的常见用例,如图:
在这里插入图片描述
Promise.all()可以接收多个promise实例,这些实例包裹成一个数组作为参数传递进去。 并且Promise.all(arr)返回一个promise,假设称为p1,可以进行.then。只有数组中所有的promise都resolved后,p1才会resolved并且结果值是一个数组,结果值数组的排列顺序和传进去的参数顺序一致。

Promise.all()方法接收一个promise的iterable类型。(Array、Map、Set都属于ES6的iterable类型)的属于,并且只返回一个promise实例。

function promiseAll(promises){
// Promise.all会返回一个promise
	return new Promise((resolve,reject)=>{
		if(!Array.isArray(promises)){
			return reject(new TypeError(`arguments must be Array`))
		}
		let count = 0
		// newValues是结果数组,最后resolve的是这个结果数组
		let newValues = new Array(promises.length)
		for(let i = 0; i < promises.length; i++){
			Promise.resolve(promises[i]).then(res=>{
				count++
				newValues[i] = res
				if(count == promises.length){
					return resolve(newValues)
				}
			},
			// 一旦有promise被拒绝,就立即reject
			// 尽管循环可能还会继续,但是没关系,all方法的promise的状态只能改变一次
			err => reject(err))
		}
	})
}

注意到没。遍历promises参数数组里的每个promise实例时,是裹在Promise.resolve里的。这是为什么呢?

按照我们想的,在内部我们要想拿到每个promise实例的resolved值,只需要调用该实例的.then方法就可以拿到。 像下面这样:

var newValues = new Array(promises.length)
for(let i = 0; i < promises.length; i++){
		promises[i].then(res=>{
			newValues[i] = res
		})
}

当然,如果你的参数里放的都是promise实例,这样当然没有问题。可是,你有时候也会这样写
在这里插入图片描述
很明显,222 这就是个普通值,它可没有.then方法。那你要这么写岂不是报错了。所以我们就用Promise.resolve() 来裹一层。把普通值222变为已经resolved为222的promise。 [p1,222,p3] 就都变成了promise实例,都可以执行promise的.then方法(注:对于已经是promise的清空,Promise.resolve也只会返回一个一模一样的副本而已. 可以看看这篇加深理解. Promise.resolve())

用途

Promise.all 可以用在处理多个异步操作时,比如说一个页面需要等到两个或者多个ajax的数据都返回后才现实, 在此之前只显示loading图标.

Promise.race()

Promise.race接收的参数和all方法一样. 区别是,race方法只要成功了一个就立刻返回.
Promise.race([p1,p2,p3]) 谁先成功就返回谁.

Promise.race = function(promises){
	if(!Array.isArray(promises)){
		return reject(new TypeError(`arguments must be Array`))
	}
	return new Promise((resolve,reject)=>{
		for(let i = 0; i < promises.length; i++){
			Promise.resolve(promises[i]).then(value=>{
			   // 期间只要有一个promise实例resolved就直接在race的promise里 resolve,即使循环还在继续也没事,因为race的promise的状态只会改变一次
				resolve(value)
			},reason =>{ reject(reason) })
		}
	})
}
用途

race的使用场景就是, 多台服务器部署了同样的服务端代码,假如我要获取一个商品列表接口, 我可以在race中写上所有服务器中的查询列表的接口地址,哪个服务器响应快,就从哪个服务器拿数据.

参考:

all方法 手写promise_promise.all的实现
理解和使用Promise.all和Promise.race

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值