Promise.all()、Promise.allSettled()原理及实现

Promise.all()

原理简述:

MDN:

  • Promise.all() 方法接收一个promise的iterable类型(注:Array,Map,Set都属于ES6的iterable类型)的输入。
  • 并且只返回一个Promise实例, 输入的所有promise的resolve回调的结果是一个数组。
  • Promise的resolve回调执行是在所有输入的promise的resolve回调都结束,或者输入的iterable里没有promise了的时候。
  • 它的reject回调执行是,只要任何一个输入的promise的reject回调执行或者输入不合法的promise就会立即抛出错误,并且reject的是第一个抛出的错误信息。
简单实现:

为了测试结果更直观一些,这里使用真实接口(来自我的博客:kayrain.cn

function fetchAction(url) {
	return new Promise((resolve, rejected) => {
		const xhr = new XMLHttpRequest();
		xhr.onreadystatechange = function() {
			if (xhr.readyState != 4) return;
			if (xhr.readyState == 4 && xhr.status == 200) {
				resolve(JSON.parse(xhr.responseText))
			} else {
				rejected('网络错误')
			}
		}
		xhr.open('get', url);
		xhr.send(null);
	})
}

const p1 = fetchAction("https://www.kayrain.cn/api/post/list?pageNo=1&pageSize=10&title=&tag=")
const p2 = fetchAction("https://www.kayrain.cn/api/post/list?pageNo=1&pageSize=10&title=&tag=")
// 将p3定义为错误请求
const p3 = fetchAction("https://www.kayrain.cn/api/post/list")

实现all():

Promise.newAll = function(promises) {
	return new Promise((resolve, reject) => {
		let list = [],
			len = promises.length,
			count = len;
		for (let i = 0; i < len; i++) {
			promises[i].then(res => {
				list[i] = res;
				if (--count === 0) {
					resolve(list)
				}
			}, error => {
				reject(error)
			})
		}
	})
} 
Promise.newAll([p1, p2, p3]).then(res => console.log('Promise.all:', res))

运行代码,由于有错误请求出现,所以打印结果为:

在这里插入图片描述

将p3改为正确请求,全部resolve后的结果为:

在这里插入图片描述

Promise.allSettled()

原理简述:

MDN:

  • Promise.allSettled()方法返回一个在所有给定的promise都已经fulfilled或rejected后的promise,并带有一个对象数组,每个对象表示对应的promise结果。
  • 当有多个彼此不依赖的异步任务成功完成时,或者总是想知道每个promise的结果时,通常使用它。
    相比之下,Promise.all() 更适合彼此相互依赖或者在其中任何一个reject时立即结束。
  • 简言之Promise.allSettled 只关心所有 promise 是不是都被 settle 了,不管其是 rejected状态的 promise,还是非 rejected状态(即fulfilled)的 promise, 都可以拿到它的最终状态并对其进行处理。
简单实现
Promise.newAllSettled = function(promises) {
	return new Promise(resolve => {
		let list = [],
			len = promises.length,
			count = len;
		for (let i = 0; i < len; i++) {
			promises[i].then(res => {
				list[i] = {
					status: 'fulfilled',
					value: res
				};
			}, error => {
				list[i] = {
					status: 'rejected',
					reason: error
				};
			}).finally(() => {
				// 循环完成后再resolve,防止出现空属性
				if (--count === 0) resolve(list);
			})
		}
	})
}

Promise.newAllSettled([p1, p2, p3]).then(res => console.log('Promise.allSettled:', res))

运行代码,打印结果为:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值