推荐答案
// www.javascriptcn.com code example
function myPromiseAll(promises) {
return new Promise((resolve, reject) => {
if (!Array.isArray(promises)) {
return reject(new TypeError('Arguments must be an array'));
}
const results = [];
let completedPromises = 0;
if (promises.length === 0) {
return resolve(results);
}
promises.forEach((promise, index) => {
Promise.resolve(promise)
.then((result) => {
results[index] = result;
completedPromises++;
if (completedPromises === promises.length) {
resolve(results);
}
})
.catch((error) => {
reject(error);
});
});
});
}本题详细解读
1. 函数定义
myPromiseAll 是一个自定义的 Promise.all 实现,它接受一个包含多个 Promise 对象的数组 promises 作为参数。
2. 参数校验
首先,函数会检查传入的参数是否是一个数组。如果不是数组,则立即返回一个被拒绝的 Promise,并抛出一个 TypeError。
if (!Array.isArray(promises)) {
return reject(new TypeError('Arguments must be an array'));
}3. 结果数组和计数器
函数内部定义了一个空数组 results 用于存储每个 Promise 的结果,以及一个计数器 completedPromises 用于跟踪已经完成的 Promise 数量。
const results = []; let completedPromises = 0;
4. 空数组处理
如果传入的 promises 数组为空,则立即返回一个已解决的 Promise,并将空数组 results 作为结果。
if (promises.length === 0) {
return resolve(results);
}5. 遍历 Promise 数组
函数遍历 promises 数组中的每个 Promise,并使用 Promise.resolve 将其转换为 Promise 对象(以防传入的不是 Promise)。然后,通过 .then 方法处理每个 Promise 的结果。
// www.javascriptcn.com code example
promises.forEach((promise, index) => {
Promise.resolve(promise)
.then((result) => {
results[index] = result;
completedPromises++;
if (completedPromises === promises.length) {
resolve(results);
}
})
.catch((error) => {
reject(error);
});
});6. 结果存储与完成判断
每当一个 Promise 完成时,将其结果存储在 results 数组的对应位置,并增加 completedPromises 计数。当所有 Promise 都完成时,调用 resolve 方法返回 results 数组。
7. 错误处理
如果任何一个 Promise 被拒绝,则立即调用 reject 方法,并将错误传递给调用者。
.catch((error) => {
reject(error);
});8. 总结
这个实现的核心思想是通过遍历 Promise 数组,逐个处理每个 Promise 的结果,并在所有 Promise 完成后返回结果数组。如果任何一个 Promise 失败,则立即返回错误。