// 若原生 Promise 不包含 .all 方法,则将其添加
if (typeof Promise.prototype.all !== 'function') {
Promise.all = function(promises) {
if (!Array.isArray(promises)) {
if (promises[Symbol.iterator]) {
promises = Array.from(promises);
} else {
throw new TypeError('Promise.all expects an array or iterable object');
}
}
return new Promise((resolve, reject) => {
// 用于存放最终结果的数组
const values = [];
// 用于记录已完成的 Promise 数量
let completedCount = 0;
// 保存输入 Promises 的总数
const totalPromises = promises.length;
// 解决单个 Promise 的处理器
const resolver = (index, value) => {
values[index] = value;
// 当所有 Promises 都完成时,解决外部的 Promise
if (++completedCount === totalPromises) {
resolve(values);
}
};
// 处理单个 Promise 的拒绝
const rejecter = (reason) => {
// 只要有一个 Promise 被拒绝,就拒绝外部的 Promise
reject(reason);
};
// 遍历传入的 Promise 数组
promises.forEach((p, index) => {
// 无论传入的 p 是否已经是 Promise,都要使用 Promise.resolve 包装
Promise.resolve(p).then(
// 成功回调,将结果存入 values 数组
value => resolver(index, value),
// 失败回调,直接拒绝外部的 Promise
rejecter
);
});
// 特殊处理:如果传入的 promises 数组为空
if (totalPromises === 0) {
// 直接解决外部的 Promise,并返回空数组
resolve([]);
}
});
};
}
// 示例:
const promises = [
fetch('https://api.example.com/data1'),
fetch('https://api.example.com/data2'),
];
Promise.all(promises)
.then(results => {
console.log('All requests succeeded:');
results.forEach((response, index) => {
response.json().then(data => console.log(`Response from ${index + 1}:`, data));
});
})
.catch(reason => console.error('At least one request failed:', reason));
Promise.all 会返回一个新的 Promise,当且仅当所有传入的 Promise 都成功解决时,新的 Promise 才会被解决,解决值是一个数组,包含了每个传入 Promise 解决的值,按照它们在数组中的位置排列。如果有任何一个 Promise 被拒绝,那么新的 Promise 也会立即被拒绝,其拒绝原因就是那个最先被拒绝的 Promise 的拒绝原因。