本文介绍如何在使用 `promise.all` 并行处理多个 promise 时,既确保所有请求完成后再统一处理结果,又能为每个已解析的 promise 单独执行回调函数,同时实现进度百分比监控。
Promise.all 的核心特性是“全量等待”:它不会在单个 Promise 解析时触发回调,而是等到所有 Promise 都成功解析后,才将结果数组一次性传递给 .then()。因此,若你想对每个响应单独执行逻辑(如日志记录、UI 更新或数据预处理),不能在 fetchData(url).then(...) 中直接调用回调(那会立即执行且与 Promise.all 无关),而应分两步处理:
以下是完整、可运行的实践示例:
function fetchData(url) {
return fetch(url)
.then(response => {
if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);
return response.json(); // 或根据需要返回 text() / blob() 等
});
}
const urls = [
'https://jsonplaceholder.typicode.com/posts/1',
'https://jsonplaceholder.typicode.com/posts/2',
'https://jsonplaceholder.typicode.com/posts/3'
];
const promises = urls.map(fetchData);
// ✅ 步骤1:独立监听每个 Promise 的完成(用于进度)
let resolvedCount = 0;
const total = promises.length;
promises.forEach((promise, index) => {
promise.then(() => {
resolvedCount++;
const progress = ((resolvedCount / total) * 100).toFixed(1);
console.log(`✅ 第 ${index + 1} 个请求完成 — 进度: ${progress}%`);
}).catch(err => {
console.warn(`⚠️ 第 ${index + 1} 个请求失败:`, err.message);
});
});
// ✅ 步骤2:Promise.all 统一处理全部成功结果
Promise.all(promises)
.then(responses => {
console.log('? 所有请求已完成,开始批量处理...');
responses.forEach((response, i) => {
// ? 在此处执行你的每个响应专属逻辑
callbackResolve(response, urls[i], i); // 示例:传入响应、URL 和索引
});
})
.catch(error => {
console.error('❌ Promise.all 失败(任一 Promise 被 reject):', error);
});
// 示例回调函数(请按需替换为你自己的逻辑)
function callbackResolve(data, url, index) {
console.log(`→ 处理第 ${index + 1} 个响应:`, { url, id: data.id, title: data.title?.substring(0, 40) + '...' });
}关键注意事项:
通过这种分离设计,你既能享受 Promise.all 的高效并发优势,又能灵活控制每个响应的生命周期行为,并获得清晰的执行进度反馈。