You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 20:13:09