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会沿着原型链向上查找,直到找到匹配的属性或者到达原型链的末端。
376 0
【JavaScript原型链prototype详解】
|
JavaScript 定位技术 API
百度离线地图API v3.0开发解决方案
百度离线地图API v3.0开发解决方案
999 0
|
安全 编译器 程序员
【C++ 修饰符关键字 explicit 】掌握C++中的explicit :构造函数行为和初始化综合指南
【C++ 修饰符关键字 explicit 】掌握C++中的explicit :构造函数行为和初始化综合指南
1007 3
|
9月前
|
前端开发
在Promise链中是否可以多次使用catch方法?
在Promise链中是否可以多次使用catch方法?
222 58
|
JavaScript 前端开发 开发者
原型链深入解析:JavaScript中的核心机制
【10月更文挑战第13天】原型链深入解析:JavaScript中的核心机制
320 0
|
XML 缓存 前端开发
Electron-builder 是如何打包 Windows 应用的?
本文首发于微信公众号“前端徐徐”,作者徐徐深入解析了 electron-builder 在 Windows 平台上的打包流程。文章详细介绍了 `winPackager.ts`、`AppxTarget.ts`、`MsiTarget.ts` 和 `NsisTarget.ts` 等核心文件,涵盖了目标创建、图标处理、代码签名、资源编辑、应用签名、性能优化等内容,并分别讲解了 AppX/MSIX、MSI 和 NSIS 安装程序的生成过程。通过这些内容,读者可以更好地理解和使用 electron-builder 进行 Windows 应用的打包和发布。
722 0
|
数据安全/隐私保护
vue-img-cutter 图片裁剪详解
vue-img-cutter 图片裁剪详解
439 1
|
前端开发 JavaScript 开发者
详细解读CSS——盒子模型(含详解)
详细解读CSS——盒子模型(含详解)
278 0
|
前端开发 JavaScript API
|
JavaScript
深入理解 uni-app 页面生命周期(二):onReady()
深入理解 uni-app 页面生命周期(二):onReady()
886 0