实现 Promise.allSettled
手写 Promise.allSettled 方法
问题
实现 Promise.allSettled,等待所有 Promise 完成(无论成功或失败),返回每个 Promise 的结果状态。
解答
Promise.myAllSettled = function (promises) {
// 将输入转为数组
const promiseArray = Array.from(promises);
// 空数组直接返回
if (promiseArray.length === 0) {
return Promise.resolve([]);
}
return new Promise((resolve) => {
const results = [];
let settledCount = 0;
promiseArray.forEach((promise, index) => {
// 用 Promise.resolve 包装,处理非 Promise 值
Promise.resolve(promise)
.then((value) => {
results[index] = { status: 'fulfilled', value };
})
.catch((reason) => {
results[index] = { status: 'rejected', reason };
})
.finally(() => {
settledCount++;
// 所有 Promise 都已 settled
if (settledCount === promiseArray.length) {
resolve(results);
}
});
});
});
};
测试
const p1 = Promise.resolve(1);
const p2 = Promise.reject('error');
const p3 = new Promise((resolve) => setTimeout(() => resolve(3), 100));
Promise.myAllSettled([p1, p2, p3]).then((results) => {
console.log(results);
// [
// { status: 'fulfilled', value: 1 },
// { status: 'rejected', reason: 'error' },
// { status: 'fulfilled', value: 3 }
// ]
});
关键点
allSettled永远返回 fulfilled 状态,不会 reject- 结果对象格式:成功是
{ status: 'fulfilled', value },失败是{ status: 'rejected', reason } - 用
Promise.resolve()包装输入,兼容非 Promise 值 - 结果数组顺序与输入顺序一致,用
index保证位置 - 与
Promise.all的区别:all遇到 reject 立即终止,allSettled等待全部完成
目录