if (typeof Promise.prototype.any !== 'function') {
Promise.any = function(promises) {
if (!Array.isArray(promises)) {
if (promises[Symbol.iterator]) {
promises = [...promises];
} else {
throw new TypeError('Promise.any expects an array or iterable object');
}
}
return new Promise((resolve, reject) => {
const results = [];
let errors = [];
let settledCount = 0;
const resolveOrRejectOne = (value, isError) => {
if (settledCount === 0) {
if (!isError) {
resolve(value);
} else {
reject(new AggregateError(errors, 'All promises were rejected'));
}
}
settledCount++;
};
promises.forEach((p, index) => {
Promise.resolve(p).then(
value => {
results[index] = value;
resolveOrRejectOne(value, false);
},
error => {
errors.push({ index, reason: error });
resolveOrRejectOne(undefined, true);
}
);
});
});
};
}
if (typeof AggregateError !== 'function') {
class AggregateError extends Error {
constructor(errors, message) {
super(message);
this.name = 'AggregateError';
this.errors = errors;
}
}
}
- 验证输入是否为可迭代对象,并转换为数组。
- 创建一个新的 Promise,其内部维护一个已解决(resolved/rejected)Promise 的计数器和错误列> 表。
- 遍历传入的 Promise 数组,对每个 Promise 使用 Promise.resolve 包装以确保得到一个 Promise 对象。
- 对每个包装后的 Promise 添加 then 回调,成功时更新结果和尝试解决新创建的 Promise,失败时将错误信息存储到错误列表并在所有 Promise 都被拒绝后拒绝新创建的 Promise。
- 如果有任何一个 Promise 成功,就直接解决新创建的 Promise 并返回其结果;如果所有 Promise 都失败,则使用 AggregateError(如果没有内置该类,则自定义一个)将所有错误合并后拒绝新创建的 Promise