0

0

如何在 Promise.all 完成后对每个已解析结果执行回调,并实时跟踪进度

心靈之曲

心靈之曲

发布时间:2026-01-15 23:35:02

|

922人浏览过

|

来源于php中文网

原创

如何在 Promise.all 完成后对每个已解析结果执行回调,并实时跟踪进度

本文介绍如何在 promise.all 全部成功完成后,安全、有序地为每个解析值执行自定义处理函数(如日志、数据转换或 dom 更新),同时通过监听单个 promise 的 .then() 实现精确的进度反馈。

Promise.all 本身不具备“逐个完成时触发回调”的能力——它只在所有 Promise 全部 resolve 后才统一返回一个包含全部结果的数组。因此,若想对每个已解析的响应单独执行逻辑(例如更新 UI 进度条、缓存中间结果或记录耗时),需采用“双层监听”策略:

  • 进度监听层:在调用 Promise.all 前,为每个原始 Promise 单独添加 .then(),用于实时统计已完成数量;
  • 结果处理层:在 Promise.all(...).then(results => {...}) 中遍历最终结果数组,对每个值执行业务逻辑(如 callbackResolve(res))。

以下是完整、可运行的实践示例:

// 示例回调函数:处理单个 fetch 响应
function callbackResolve(response) {
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  return response.json(); // 或其他转换逻辑
}

// 封装 fetch 并支持错误捕获(推荐)
function fetchData(url) {
  return fetch(url)
    .catch(err => {
      console.error(`Fetch failed for ${url}:`, err);
      throw err; // 确保 Promise.all 能捕获失败
    });
}

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.all)
let resolvedCount = 0;
promises.forEach((promise, index) => {
  promise.then(() => {
    resolvedCount++;
    const progress = ((resolvedCount / promises.length) * 100).toFixed(1);
    console.log(`✅ [Progress] ${resolvedCount}/${promises.length} (${progress}%)`);
  }).catch(err => {
    console.warn(`⚠️  Request ${index + 1} failed, but progress continues...`);
  });
});

// ? 步骤2:统一结果处理(Promise.all 完成后执行)
Promise.all(promises)
  .then(responses => {
    console.log('? All requests completed. Processing results...');
    // 对每个响应执行 callbackResolve(支持链式操作)
    return Promise.all(responses.map(callbackResolve));
  })
  .then(dataArray => {
    console.log('? Final processed data:', dataArray);
    // ✅ 此处可安全进行渲染、存储或后续聚合操作
  })
  .catch(error => {
    console.error('❌ Promise.all rejected:', error);
  });

关键注意事项:

ChartGen
ChartGen

AI快速生成专业数据图表

下载
  • ⚠️ 避免在 map(fetchData) 中直接 .then(callbackResolve):这会导致回调立即执行(因 fetch() 返回 Promise,.then() 立即注册但不等待),且 Promise.all 将接收 undefined 或非 Promise 值,破坏并行性;
  • ⚠️ 进度统计需用 let 变量 + 闭包:确保每个 .then() 共享同一计数器,而非使用 for...of 中未声明的变量(原文代码中 resolveProgres++ 存在拼写错误,已修正为 resolvedCount);
  • 推荐搭配 Promise.allSettled:若需容忍部分失败(如网络抖动),可用 Promise.allSettled 替代,并在 .then() 中过滤 status: 'fulfilled' 的项再处理;
  • 现代替代方案考虑 AbortController 或 Promise.race:对超时控制、取消请求等高级需求,应结合信号机制实现。

通过该模式,你既能享受 Promise.all 的高效并发优势,又能精准掌控每个请求的生命周期与结果流——真正实现“并行发起、顺序处理、实时可见”。

相关专题

更多
go语言闭包相关教程大全
go语言闭包相关教程大全

本专题整合了go语言闭包相关数据,阅读专题下面的文章了解更多相关内容。

133

2025.07.29

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

75

2025.09.05

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

32

2025.11.16

golang map原理
golang map原理

本专题整合了golang map相关内容,阅读专题下面的文章了解更多详细内容。

59

2025.11.17

java判断map相关教程
java判断map相关教程

本专题整合了java判断map相关教程,阅读专题下面的文章了解更多详细内容。

36

2025.11.27

undefined是什么
undefined是什么

undefined是代表一个值或变量不存在或未定义的状态。它可以作为默认值来判断一个变量是否已经被赋值,也可以用于设置默认参数值。尽管在不同的编程语言中,undefined可能具有不同的含义和用法,但理解undefined的概念可以帮助我们更好地理解和编写程序。本专题为大家提供undefined相关的各种文章、以及下载和课程。

4682

2023.07.31

网页undefined是什么意思
网页undefined是什么意思

网页undefined是指页面出现了未知错误的意思,提示undefined一般是在开发网站的时候定义不正确或是转换不正确,或是找不到定义才会提示undefined未定义这个错误。想了解更多的相关内容,可以阅读本专题下面的文章。

2951

2024.08.14

网页undefined啥意思
网页undefined啥意思

本专题整合了undefined相关内容,阅读下面的文章了解更多详细内容。后续继续更新。

193

2025.12.25

Golang gRPC 服务开发与Protobuf实战
Golang gRPC 服务开发与Protobuf实战

本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

8

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 8.3万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 3.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号