用代码示例演示如何使用Promise.allSettled()处理异步操作

简介: 用代码示例演示如何使用Promise.allSettled()处理异步操作

下面通过 “批量上传文件” 这个真实场景,演示如何使用 Promise.allSettled() 处理多个异步操作——即使部分文件上传失败,也能获取所有文件的上传结果(成功/失败状态),并最终统计结果、提示用户。

代码示例:批量文件上传(模拟)

// 1. 模拟单个文件上传的异步操作(返回Promise)
// 参数:fileName(文件名)、successRate(成功概率,0-1之间,用于模拟失败场景)
function uploadFile(fileName, successRate = 0.7) {
   
  return new Promise((resolve, reject) => {
   
    // 模拟上传耗时(1-3秒随机延迟,更贴近真实网络情况)
    const delay = Math.random() * 2000 + 1000;

    setTimeout(() => {
   
      // 随机模拟成功/失败(根据successRate控制概率)
      const isSuccess = Math.random() < successRate;
      if (isSuccess) {
   
        // 成功:返回上传结果(文件名、URL、大小)
        resolve({
   
          fileName,
          status: "success",
          fileUrl: `https://example.com/uploads/${
     fileName}`,
          size: Math.floor(Math.random() * 10) + 1 // 模拟文件大小(1-10MB)
        });
      } else {
   
        // 失败:返回错误原因
        reject(new Error(`文件 "${
     fileName}" 上传失败:网络波动或文件损坏`));
      }
    }, delay);
  });
}

// 2. 准备待上传的文件列表(模拟用户选择的5个文件)
const filesToUpload = [
  "report_2024.pdf",
  "avatar.png",
  "meeting_notes.docx",
  "data_backup.zip",
  "presentation.pptx"
];

// 3. 生成所有文件的上传Promise数组
const uploadPromises = filesToUpload.map(fileName => {
   
  // 为每个文件创建上传Promise(成功概率设为0.6,故意让部分文件失败)
  return uploadFile(fileName, 0.6);
});

// 4. 使用Promise.allSettled()处理所有上传操作
console.log("开始批量上传文件...");
Promise.allSettled(uploadPromises)
  .then(allResults => {
   
    // 4.1 统计成功/失败数量
    let successCount = 0;
    let failCount = 0;
    const successFiles = []; // 存储成功的文件信息
    const failFiles = [];    // 存储失败的文件信息

    // 4.2 遍历所有结果,分类处理
    allResults.forEach((result, index) => {
   
      const fileName = filesToUpload[index]; // 对应原文件列表的文件名
      if (result.status === "fulfilled") {
   
        // 成功:收集信息,计数+1
        successCount++;
        successFiles.push(result.value);
      } else {
   
        // 失败:收集错误信息,计数+1
        failCount++;
        failFiles.push({
   
          fileName,
          errorMsg: result.reason.message // 提取错误原因
        });
      }
    });

    // 4.3 输出最终统计结果(用户友好的提示)
    console.log("\n=== 批量上传完成 ===");
    console.log(`总文件数:${
     filesToUpload.length} | 成功:${
     successCount} | 失败:${
     failCount}`);

    if (successFiles.length > 0) {
   
      console.log("\n✅ 成功上传的文件:");
      successFiles.forEach(file => {
   
        console.log(`- ${
     file.fileName}${
     file.size}MB):${
     file.fileUrl}`);
      });
    }

    if (failFiles.length > 0) {
   
      console.log("\n❌ 上传失败的文件:");
      failFiles.forEach(file => {
   
        console.log(`- ${
     file.fileName}${
     file.errorMsg}`);
      });
    }
  })
  .catch(error => {
   
    // 注意:Promise.allSettled()本身不会reject,这里的catch几乎不会触发
    console.error("批量上传过程中发生未知错误:", error.message);
  });

代码解析:

  1. uploadFile 函数
    模拟单个文件的异步上传,通过随机延迟(1-3秒)和成功概率(successRate)模拟真实网络的不确定性,成功时返回文件上传信息,失败时抛出错误。

  2. 生成 Promise 数组
    map 遍历待上传文件列表,为每个文件创建一个上传 Promise,组成 uploadPromises 数组(这是 Promise.allSettled() 的输入)。

  3. Promise.allSettled() 核心逻辑

    • 等待所有文件上传完成(无论成功或失败),不会因某个文件失败而提前终止。
    • 接收的 allResults 是一个数组,每个元素对应一个上传操作的结果,结构为:
      • 成功:{ status: "fulfilled", value: 成功结果 }
      • 失败:{ status: "rejected", reason: 错误对象 }
  4. 结果统计与展示
    遍历 allResults,分类统计成功/失败的文件数量,提取关键信息(如成功文件的 URL、失败文件的错误原因),最终以用户友好的格式输出,方便后续处理(如重试失败文件)。

运行效果示例(每次运行可能不同,因随机因素):

开始批量上传文件...

=== 批量上传完成 ===
总文件数:5 | 成功:3 | 失败:2

✅ 成功上传的文件:
- report_2024.pdf(5MB):https://example.com/uploads/report_2024.pdf
- avatar.png(2MB):https://example.com/uploads/avatar.png
- presentation.pptx(8MB):https://example.com/uploads/presentation.pptx

❌ 上传失败的文件:
- meeting_notes.docx:文件 "meeting_notes.docx" 上传失败:网络波动或文件损坏
- data_backup.zip:文件 "data_backup.zip" 上传失败:网络波动或文件损坏

核心优势:

  • 不“快速失败”:即使部分异步操作失败,也能获取所有操作的结果,适合需要“全量统计”的场景(如批量任务、报表生成)。
  • 结果清晰:每个操作的状态和结果都被明确标记,便于后续分类处理(如重试失败任务、记录日志)。
目录
相关文章
如何添加新的源到nrm?
如何添加新的源到nrm?
453 127
Element Plus 日期选择器 获取选中的日期的格式(当前日期/时间戳格式)
Element Plus 日期选择器 获取选中的日期的格式(当前日期/时间戳格式)
1629 0
|
4月前
|
前端开发 容器
CSS-Flex布局
CSS Flex弹性布局是移动端/响应式开发的核心方案,通过「容器+项目」模型实现灵活空间分配与对齐。本文详解核心概念、容器/项目属性,并结合评论框代码实战拆解,助新手快速掌握justify-content、align-items、flex:1等关键用法。(239字)
701 5
|
8月前
|
前端开发 数据处理
Promise的then方法可以返回一个非Promise的值吗?如果可以,这对链式调用有什么影响?
Promise的then方法可以返回一个非Promise的值吗?如果可以,这对链式调用有什么影响?
329 121
|
8月前
|
前端开发
Promise的then方法返回的新Promise对象的状态为“成功(Resolved)”时,链式调用会如何执行?
Promise的then方法返回的新Promise对象的状态为“成功(Resolved)”时,链式调用会如何执行?
294 0
|
10月前
|
机器学习/深度学习 人工智能 机器人
Meta AI Research:虚拟/可穿戴/机器人三位一体的AI进化路径
本文阐述了我们对具身AI代理的研究——这些代理以视觉、虚拟或物理形式存在,使其能够与用户及环境互动。这些代理包括虚拟化身、可穿戴设备和机器人,旨在感知、学习并在其周围环境中采取行动。与非具身代理相比,这种特性使它们更接近人类的学习与环境交互方式。我们认为,世界模型的构建是具身AI代理推理与规划的核心,这使代理能够理解并预测环境、解析用户意图及社会背景,从而增强其自主完成复杂任务的能力。世界建模涵盖多模态感知的整合、通过推理进行行动规划与控制,以及记忆机制,以形成对物理世界的全面认知。除物理世界外,我们还提出需学习用户的心理世界模型,以优化人机协作。
762 3
|
编解码 人工智能 缓存
通义万相重磅升级,成功登顶VBench,阿里云百炼邀您第一时间体验
阿里云通义万相推出2.1视频生成模型,大幅提升复杂运动、物理规律遵循及艺术表现,在权威评测VBench中夺冠。新模型采用自研VAE和DiT架构,增强时空上下文建模,实现更稳定的大幅度肢体运动和多对象生成。通义万相支持中英文文字特效生成,满足广告设计、短视频等创作需求,并在阿里云百炼平台开放API调用,提供免费试用资源。
1776 0
|
网络协议 物联网 数据处理
C语言在网络通信程序实现中的应用,介绍了网络通信的基本概念、C语言的特点及其在网络通信中的优势
本文探讨了C语言在网络通信程序实现中的应用,介绍了网络通信的基本概念、C语言的特点及其在网络通信中的优势。文章详细讲解了使用C语言实现网络通信程序的基本步骤,包括TCP和UDP通信程序的实现,并讨论了关键技术、优化方法及未来发展趋势,旨在帮助读者掌握C语言在网络通信中的应用技巧。
536 2
|
机器学习/深度学习 人工智能 异构计算
【Docker 专栏】Docker 与 GPU 加速应用的结合
【5月更文挑战第9天】GPU加速技术在处理大规模数据和复杂计算时展现强大性能,尤其在AI和深度学习领域。Docker作为轻量级容器化工具,提供隔离、可移植和高效的环境。结合GPU加速,关键在于容器访问GPU设备和安装相应驱动。NVIDIA提供了支持工具,允许Docker利用GPU。应用场景包括人工智能、科学计算和视频处理。优势包括资源利用率提升和部署灵活性,但面临驱动兼容性、资源管理和监控调试的挑战。未来,随着技术发展,Docker与GPU加速在边缘计算中的应用将有广阔前景。
868 1
【Docker 专栏】Docker 与 GPU 加速应用的结合