如何在Promise.all中为每个已解析Promise执行函数并获取进度?
解决Promise.all单Promise回调与进度追踪问题
一、为每个已解析的Promise执行回调
你遇到的问题核心是:Promise.all仅负责等待所有Promise完成,但单个Promise在map阶段就已经启动执行了,直接给单个Promise加.then()确实会在它自身完成时就触发回调,而非等待Promise.all。但我们可以在保留原始Promise结果的前提下,给每个Promise附加回调逻辑,既不影响Promise.all的最终结果,又能在单个Promise完成时执行你需要的操作。
两种实现方式任选其一:
方式1:修改fetchData函数
async function fetchData(url) { const response = await fetch(url); // 单个Promise完成后立即执行回调 callbackResolve(response); return response; // 必须返回原始结果,保证Promise.all能拿到正确数据 } // 定义你的回调函数 function callbackResolve(response) { console.log(`单个请求完成:${response.url}`); } Promise.all(urls.map(fetchData)) .then(allResults => { console.log('所有请求全部完成', allResults); });
方式2:在map时包装Promise(不修改原fetchData)
// 定义你的回调函数 function callbackResolve(response) { console.log(`单个请求完成:${response.url}`); } const wrappedPromises = urls.map(url => fetchData(url).then(response => { callbackResolve(response); return response; // 务必返回原始结果,否则Promise.all会拿到undefined }) ); Promise.all(wrappedPromises) .then(allResults => { console.log('所有请求全部完成', allResults); });
二、追踪Promise.all的执行进度
要获取执行进度,只需维护一个计数器,每个Promise完成(无论成功失败)时更新计数器,再计算完成比例即可:
let completedCount = 0; const total = urls.length; // 进度更新函数 function updateProgress() { completedCount++; const progress = Math.round((completedCount / total) * 100); console.log(`当前进度:${progress}%`); // 这里可以对接UI进度条、状态提示等逻辑 } // 包装Promise,确保无论成功失败都更新进度 const processedPromises = urls.map(url => fetchData(url) .then(response => { callbackResolve(response); return response; }) .catch(error => { console.error(`请求${url}失败:`, error); return error; // 返回错误标识,方便后续区分成功/失败结果 }) .finally(() => { updateProgress(); // 无论成功失败都更新进度 }) ); Promise.all(processedPromises) .then(allResults => { console.log('所有请求处理完毕'); // 可在这里过滤成功/失败结果 const successes = allResults.filter(res => res instanceof Response); const failures = allResults.filter(res => res instanceof Error); console.log(`成功:${successes.length}个,失败:${failures.length}个`); });
完整示例代码
// 单个请求完成后的回调 function callbackResolve(response) { console.log(`请求完成:${response.url}`); } // 进度追踪相关 let completedCount = 0; const totalUrls = urls.length; function updateProgress() { completedCount++; const progress = Math.round((completedCount / totalUrls) * 100); console.log(`当前进度:${progress}%`); } async function fetchData(url) { return await fetch(url); } // 处理所有Promise const processedPromises = urls.map(url => fetchData(url) .then(response => { callbackResolve(response); return response; }) .catch(err => { console.error(`请求${url}失败:`, err); return err; }) .finally(() => { updateProgress(); }) ); // 等待全部完成 Promise.all(processedPromises) .then(allResults => { console.log('所有请求处理完毕'); const successes = allResults.filter(res => res instanceof Response); const failures = allResults.filter(res => res instanceof Error); console.log(`成功:${successes.length}个,失败:${failures.length}个`); });
内容的提问来源于stack exchange,提问作者Guilherme Rigotti
相关产品推荐
相关产品推荐

