一,前言
上一篇,主要实现了 Promise 静态 API(类方法):Promise.race
,主要涉及以下几个点:
- 测试原生 Promise.race 的使用;
- Promise.race 的功能与特性分析;
- Promise.race 的源码实现、执行分析、功能测试;
本篇,继续实现 Promise 静态 API:Promise.allSettled
和 Promise.any
;
二,Promise.allsettled 简介
1,API 介绍
MDN 参考资料
Promise.allsettled
:
- 批处理 promise,返回 promise;
- 存在失败结果也会拿到全部执行结果,不会走 catch;
- 解决了 Promise.all 不能拿到失败执行结果的问题;
2,原生 Promise.allsettled 功能测试
// p1:立即成功
const p1 = Promise.resolve("p1_success");
// p2:2 秒后成功
const p2 = new Promise((resolve, reject) => setTimeout(resolve, 2000, 'p2_success'));
// p3:1 秒后失败
const p3 = new Promise((resolve, reject) => setTimeout(reject, 1000, 'p3_success'));
Promise.allSettled([p1, p2, p3, 1]).
then((results) => results.forEach((result) => console.log(result)));
// 执行结果:2 秒后全部执行完成
{ status: 'fulfilled', value: 'p1_success' }
{ status: 'fulfilled', value: 'p2_success' }
{ status: 'rejected', reason: 'p3_success' }
{ status: 'fulfilled', value: 1 }
- allSettled 现象:
全部执行完成,返回执行结果数组(下标与按执行顺序一致)
三,Promise.allsettled 实现
1,原理分析
Promise.allsettled
:入参是一个 promise 集合;返回一个 Promise 实例;
Promise.allsettled
内部return new Promise(...)
- 所有 promise 都会被执行完,并且按照执行顺序返回执行结果;
Promise.allsettled
不会走 reject,按执行顺序全部收集到数组后 resolve 返回即可;
2,代码实现
// allSettle:全部执行完成后,返回全部执行结果(成功+失败)
static allSettled(promises) {
const result = new Array(promises.length); // 记录执行的结果:用于返回直接结果
let times = 0; // 记录执行完成的次数:判断是否完成
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
let p = promises[i];
if (p && typeof p.then === 'function') {
p.then((data) => {
result[i] = { status: 'fulfilled', value: data }
times++;
if (times === promises.length) {
resolve(result);
}
}).catch(err => {
result[i] = { status: 'rejected', reason: err }
times++;
if (times === promises.length) {
resolve(result);
}
})
} else { // 普通值,加入
result[i] = { status: 'fulfilled', value: p }
times++;
if (times === promises.length) {
resolve(result);
}
}
}
})
}
四,Promise.any 简介
1,API 介绍
MDN 参考资料
Promise.any
:
- 批处理 promise,返回 promise;
- 返回第一个成功结果,全部失败才返回失败;
- 解决了 Promise.race 只能拿到第一个执行完成(不管成功/失败)的结果;
五,Promise.any 实现
1,原理分析
Promise.any
:入参是一个 promise 集合;返回一个 Promise 实例;
Promise.any
内部return new Promise(...)
- 执行所有 promise,使用最先返回的成功结果;全部失败才判定为失败;
p.then("谁先成功就返回谁","失败了先存起来,都失败了才返回")
2,代码实现
// any:一个成功就成功,全部失败才失败
static any(promises) {
const rejectedArr = []; // 记录失败的结果
let rejectedTimes = 0; // 记录失败的次数
return new Promise((resolve, reject) => {
if(promises == null || promises.length == 0){
reject("无效的 any");
}
for (let i = 0; i < promises.length; i++) {
let p = promises[i];
// 处理 promise
if (p && typeof p.then === 'function') {
p.then((data) => {
resolve(data) // 使用最先成功的结果
}, (err) => { // 如果失败了,保存错误信息;当全失败时,any 才失败
rejectedArr[i] = err;
rejectedTimes++;
if (rejectedTimes === promises.length) {
reject(rejectedArr);
}
})
}else{// 处理普通值,直接成功
resolve(p)
}
}
})
}
3,功能测试
const pErr = new Promise((resolve, reject) => {
setTimeout(reject, 1000, "失败了");
});
const pSlow = new Promise((resolve, reject) => {
setTimeout(resolve, 5000, "慢的成功");
});
const pFast = new Promise((resolve, reject) => {
setTimeout(resolve, 2000, "快的成功");
});
Promise.any([pErr, pSlow, pFast]).then((value) => {
console.log("Promise.any 成功", value);
}).catch(err =>{
console.log("Promise.any 失败", err);
})
// 执行结果:
2 秒后返回:"Promise.any 成功 快的成功";
5 秒后执行完成;
六,结尾
本篇,主要实现 Promise 静态 API:Promise.allSettled
和 Promise.any
,主要涉及以下几个点:
- 测试原生 Promise.allsettled 的使用;
- Promise.allsettled 原理分析、源码实现、功能测试;
- Promise.any 原理分析、源码实现、功能测试;
下一篇,实现一个 promisify 工具函数;
维护记录
- 20211120
- 修改结尾部分,更新文章摘要