Promise的then方法返回的新Promise对象的状态为“失败(Rejected)”时,链式调用会如何执行?

简介: Promise的then方法返回的新Promise对象的状态为“失败(Rejected)”时,链式调用会如何执行?

当 Promise 的 then() 方法返回的新 Promise 状态为 失败(Rejected) 时,链式调用会遵循“错误冒泡”机制,具体执行规则如下:

1. 直接触发下一个 then() 的失败回调(若提供)

如果链式调用的下一个 then() 提供了第二个参数(onRejected 失败回调),则该回调会被立即触发,接收当前失败的原因作为参数。

示例:

Promise.resolve()
  .then(() => {
   
    // 第一个 then() 返回失败的新 Promise
    return Promise.reject(new Error("操作失败"));
  })
  .then(
    // 成功回调(不会执行,因为前一个 Promise 失败)
    () => console.log("这里不会执行"),
    // 失败回调(会执行,接收错误原因)
    (error) => {
   
      console.log("捕获错误:", error.message); // 输出:捕获错误:操作失败
      return "错误已处理"; // 返回普通值,新 Promise 变为成功状态
    }
  )
  .then((result) => {
   
    // 前一个 then() 已处理错误,状态变为成功,这里会执行
    console.log("后续操作:", result); // 输出:后续操作:错误已处理
  });

2. 若下一个 then() 未提供失败回调,错误会“冒泡”传递

如果下一个 then() 只提供了成功回调(或未提供任何回调),则失败状态会跳过当前 then(),继续向后传递,直到遇到第一个提供失败回调的 then()catch()

示例:

Promise.resolve()
  .then(() => {
   
    throw new Error("原始错误"); // 返回失败的新 Promise
  })
  .then((result) => {
   
    // 未提供失败回调,错误会跳过当前 then()
    console.log("这里不会执行");
  })
  .then(
    (result) => console.log("这里也不会执行"), // 继续跳过
    (error) => {
   
      // 遇到提供失败回调的 then(),触发执行
      console.log("最终捕获:", error.message); // 输出:最终捕获:原始错误
    }
  );

3. catch() 本质是 then(null, onRejected),会捕获冒泡的错误

catch() 方法是 then(null, onRejected) 的语法糖,专门用于捕获错误。当失败状态冒泡到 catch() 时,会触发其回调函数。

示例:

Promise.resolve()
  .then(() => {
   
    return Promise.reject(new Error("网络异常")); // 返回失败的新 Promise
  })
  .then((data) => {
   
    // 未处理错误,错误继续冒泡
    console.log("处理数据"); // 不会执行
  })
  .catch((error) => {
   
    // catch() 捕获到冒泡的错误
    console.log("错误处理:", error.message); // 输出:错误处理:网络异常
    return "恢复正常"; // 返回成功结果,后续 then() 可继续执行
  })
  .then((result) => {
   
    // catch() 处理后状态变为成功,这里会执行
    console.log("继续操作:", result); // 输出:继续操作:恢复正常
  });

总结

then() 返回的新 Promise 状态为失败时,链式调用会:

  • 优先寻找下一个 then() 中的失败回调(第二个参数)进行处理;
  • 若未找到,则错误会一直“冒泡”,直到被某个 catch() 捕获;
  • 错误被处理后(回调正常返回结果),后续的 then() 会继续执行(基于新的成功状态)。

这种机制保证了异步操作中的错误能被集中处理,避免了代码中到处充斥错误处理逻辑,使链式调用更加简洁清晰。

目录
相关文章
|
前端开发 JavaScript
【JavaScript原型链prototype详解】
在JavaScript中,每个对象都有一个原型(prototype)属性,它指向另一个对象。这个被指向的对象也有自己的原型,以此类推,最终形成了一个原型链。原型链的顶端是Object.prototype,它是所有对象的根原型。 当我们访问一个对象的属性时,如果该对象自身没有这个属性,JavaScript会沿着原型链向上查找,直到找到匹配的属性或者到达原型链的末端。
335 0
【JavaScript原型链prototype详解】
|
安全 编译器 程序员
【C++ 修饰符关键字 explicit 】掌握C++中的explicit :构造函数行为和初始化综合指南
【C++ 修饰符关键字 explicit 】掌握C++中的explicit :构造函数行为和初始化综合指南
973 3
|
人工智能 自然语言处理 测试技术
使用 GPT4 和 ChatGPT 开发应用:第四章到第五章
使用 GPT4 和 ChatGPT 开发应用:第四章到第五章
327 0
|
前端开发 JavaScript 开发者
详细解读CSS——盒子模型(含详解)
详细解读CSS——盒子模型(含详解)
212 0
|
11月前
|
数据可视化 项目管理 开发工具
Git 可视化的实现:提升版本控制体验的利器
Git是最流行的分布式版本控制系统,广泛用于软件开发和项目管理。但其命令行操作复杂,难以直观理解,尤其是涉及分支和合并时。为此,Git可视化工具应运而生,通过图形界面帮助开发者更清晰地理解项目历史、分支结构及变更情况。本文将探讨Git可视化的概念背景、技术方法及相关工具,包括GitKraken、Sourcetree、Gitg、Git Extensions和Tig等,帮助读者掌握其在日常工作中的应用,提升版本管理效率。此外,还将介绍如何结合可视化项目管理工具,如板栗看板,实现更高效的团队协作和任务管理。
234 0
|
11月前
|
存储 大数据 Apache
大数据-146 Apache Kudu 安装运行 Dockerfile 模拟集群 启动测试
大数据-146 Apache Kudu 安装运行 Dockerfile 模拟集群 启动测试
117 0
|
数据库
MyBatisPlus-乐观锁概念及实现步骤
MyBatisPlus-乐观锁概念及实现步骤
232 0
|
负载均衡 应用服务中间件 Linux
在Linux中,Nginx如何实现负载均衡分发策略?
在Linux中,Nginx如何实现负载均衡分发策略?
|
编解码 自然语言处理 前端开发
Web Audio API 第3章 音量和响度
Web Audio API 第3章 音量和响度
|
存储 编译器 C语言
C语言程序设计——字符输出函数putchar()
C语言程序设计——字符输出函数putchar()