手写promise原理系列八:封装Promise.all方法,Promise.all的用法

在这里插入图片描述

小伙伴们,你们好,“手写promise原理系列” 马上进入尾声了,我打算出到"手写promise原理系列九"便结束了。

为什么要出到系列九呢?大概是因为九这个数字吧!中国传统文化中,"十"是满盈之数,物极必反,盛极必衰,所以自谨待之;而"九"为百尺竿头更进一步,也希望自己能爬到百尺竿头,更进一步。九也为极之数,阳之数;在易经中,阳爻(yao)用九,阴爻用六,而乾卦为六个阳爻组成,《大象传》为乾卦立义为:天行健,君子以自强不息。

扯远了,回归正题。

当前章节探讨一下 Promise.all 方法的用法以及封装。

all 单词的释义我们可以知道是 全部 的意思,其实就是全部 promise 对象执行成功才返回结果,只要有一个失败,就返回失败的结果。

先来看失败的调用方式:

let p1 = new Promise((resolve, reject) => {
	resolve("111");
});
let p2 = Promise.reject("222"); // 改变状态为失败 reject
let p3 = Promise.resolve("333");
let result = Promise.all([p1, p2, p3]); // 参数为 promise 对象组成的数组
console.log(result);

在这里插入图片描述
Promise.all 方法的参数是一个 promise 对象组成的数组,当 Promise.all 方法的参数中有一个失败的状态时,直接返回当前失败的 promise 对象的状态以及结果。

再来看同步执行成功的调用方式:

let p1 = new Promise((resolve, reject) => {
	resolve("111");
});
let p2 = Promise.resolve("222");
let p3 = Promise.resolve("333");
let result = Promise.all([p1, p2, p3]);
console.log(result);

在这里插入图片描述

还有异步执行成功的调用方式:

let p1 = new Promise((resolve, reject) => {
	setTimeout(()=>{
		resolve("111");
	}, 1000)
});
let p2 = Promise.resolve("222");
let p3 = Promise.resolve("333");
let result = Promise.all([p1, p2, p3]);
console.log(result);

在这里插入图片描述
由上面的同步、异步调用方式可知,不管 promise 对象是同步改变状态还是异步改变状态,Promise.all 的执行结果都是有序的。正常来说异步执行时,结果应该是"222"、"333"、"111",因为resolve("111")是异步任务,在最后执行,他们三个的执行顺序应该是 p2–>p3–>p1。可是显示的结果却是 p1–>p2–>p3,这是为什么呢?

其实,关键点在于异步改变状态时,如何让 Promise.all 的执行结果变为有序的?很简单,在这里使用数组的下标赋值法arr[1] = "222"; arr[2] = "333"; arr[0] = "111"。这样得到的结果肯定是按顺序的 ["111", "222", "333"] ,因为根据数组下标来进行赋值操作时,就跟代码的执行顺序无关了。

let arr = new Array(3);  // 创建 length 为3的空数组 arr
arr[1] = 222;
console.log(arr);
arr[2] = 333;
console.log(arr);
arr[0] = 111;
console.log(arr);

在这里插入图片描述

Promise.all 方法封装的代码

Promise.all = function(promiseArray){
	return new Promise((resolve, reject) => {
		// 定义 Promise.all 方法的返回值
		let arr = [];
		// 循环处理 promise 对象
		for(let i = 0; i < promiseArray.length; i++){
			let p = promiseArray[i];
			// 调用每一个 promise 对象的 then 方法,获取结果
			p.then((value) => {
				// 根据数组下标赋值,保证 promise 对象返回正确的结果
				arr[i] = value;
				// 判断是否所有的 promise 对象都执行完毕,若全部执行完毕,则返回结果
				if (arr.length === promiseArray.length) {
					resolve(arr);
				}			
			}, reason => {
				// 状态变为失败时,直接返回结果
				reject(reason);
			})
		}
	})
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值