Promise实例的catch方法和then方法中的失败回调有什么区别?

简介: Promise实例的catch方法和then方法中的失败回调有什么区别?

Promise 实例的 catch() 方法和 then() 方法的第二个参数(失败回调)都能处理异步操作的失败,但它们在错误捕获范围使用场景上有明显区别:

1. 本质区别:错误捕获范围不同

  • then() 的第二个参数(onRejected
    只能捕获当前 Promise 自身的失败(即上一个 Promise 直接抛出的错误),无法捕获自身成功回调(onFulfilled)中产生的错误

  • catch() 方法
    本质是 then(null, onRejected) 的语法糖,但它能捕获整个链式调用中所有上游的错误,包括:

    • 前面 Promise 直接抛出的错误;
    • 前面 then() 的成功回调(onFulfilled)中抛出的错误。

2. 代码示例对比

示例 1:then() 的失败回调无法捕获自身成功回调的错误

Promise.reject(new Error("原始错误"))
  .then(
    // 成功回调(不会执行,因为上一个 Promise 失败)
    () => console.log("成功回调"),
    // 失败回调:只能捕获上一个 Promise 的错误
    (error) => {
   
      console.log("then的失败回调捕获:", error.message); // 输出:原始错误
      throw new Error("在失败回调中新增的错误"); // 这里抛出的错误,当前then无法捕获
    }
  )
  .then(
    () => console.log("后续成功回调"), // 不会执行
    (error) => {
   
      console.log("后续then的失败回调捕获:", error.message); // 输出:在失败回调中新增的错误
    }
  );

示例 2:catch() 能捕获链式调用中所有上游错误

Promise.resolve()
  .then(() => {
   
    throw new Error("成功回调中抛出的错误"); // 这里的错误会被后续catch捕获
  })
  .catch((error) => {
   
    console.log("catch捕获:", error.message); // 输出:成功回调中抛出的错误
    throw new Error("在catch中新增的错误"); // 这里的错误会被下一个catch捕获
  })
  .catch((error) => {
   
    console.log("下一个catch捕获:", error.message); // 输出:在catch中新增的错误
  });

3. 使用场景区别

  • 优先使用 catch() 的场景
    大多数情况下,推荐用 catch() 统一处理错误,因为它能捕获链式调用中所有可能的错误(包括成功回调中意外抛出的错误),代码更简洁、容错性更强。

    fetchData()
      .then(data => {
         
        // 处理数据(可能意外抛错)
        if (!data) throw new Error("数据为空");
        return processData(data);
      })
      .then(processedData => saveData(processedData))
      .catch(error => {
         
        // 统一处理所有错误:网络请求失败、数据处理失败、保存失败等
        console.error("操作失败:", error.message);
      });
    
  • 使用 then() 失败回调的场景
    当需要针对特定 Promise 的失败做单独处理,且不希望影响后续链式调用时(处理后可返回新结果让链条继续执行)。

    fetchData()
      .then(
        data => processData(data),
        // 仅处理fetchData的失败,不影响后续流程
        error => {
         
          console.log("请求失败,使用默认数据");
          return getDefaultData(); // 返回默认数据,让链条继续执行
        }
      )
      .then(data => saveData(data)) // 无论前面是成功还是失败处理,这里都会执行
      .catch(error => {
         
        // 仅捕获processData或saveData的错误
        console.error("处理或保存失败:", error.message);
      });
    

总结

特性 then() 的失败回调(第二个参数) catch() 方法
本质 仅处理当前 Promise 的直接失败 then(null, onRejected) 的语法糖
错误捕获范围 只能捕获上一个 Promise 的失败 能捕获链式调用中所有上游错误(包括成功回调中的错误)
适用场景 特定 Promise 的单独失败处理 统一捕获整个链条的所有错误

实际开发中,catch() 因更全面的错误捕获能力,使用频率更高;then() 的失败回调则适合针对性处理特定环节的错误。

目录
相关文章
|
2月前
|
前端开发 BI
用代码示例演示如何使用Promise.allSettled()处理异步操作
用代码示例演示如何使用Promise.allSettled()处理异步操作
267 127
|
2月前
|
Web App开发 移动开发 前端开发
H5页面适配大屏和小屏的方案
H5页面适配大屏和小屏的方案
286 62
|
2月前
|
API PHP 开发者
别再混淆 PHP8.1 中纤程 Fibers 和协程 Coroutines 了 一文搞懂它们的区别
协程是可暂停的函数,PHP通过yield实现;Fibers是PHP 8.1+的轻量执行单元,可手动控制执行流程。协程适用于异步I/O,Fibers更灵活,为异步框架提供底层支持,让PHP能写出同步风格的异步代码,提升并发性能。(239字)
432 5
|
3月前
|
缓存 安全 Windows
错误代码0x80004005解决办法分享
以下是解决Windows系统错误代码0x80004005的多种方法,综合了多个高可信度来源的建议:
uni-app监听页面滚动
uni-app监听页面滚动
835 0
|
数据采集 监控 JavaScript
网站流量日志分析 —数据采集—页面埋点 JavaScript 收集数据|学习笔记
快速学习网站流量日志分析—数据采集—页面埋点 JavaScript 收集数据
781 0
网站流量日志分析 —数据采集—页面埋点 JavaScript 收集数据|学习笔记
|
5月前
|
前端开发 JavaScript 流计算
React 18 流式渲染:解锁极致性能优化实践
React 18 流式渲染:解锁极致性能优化实践
341 80
|
安全 Unix Linux
Unix是什么?
Unix是什么?
984 2
|
7月前
|
JSON 前端开发 JavaScript
搞定 XLSX 预览?别瞎找了,这几个库(尤其最后一个)真香!
本文来自【沉浸式趣谈】,探讨前端处理Excel的三大主流库:xlsx、Handsontable和ExcelJS。 - **xlsx**:轻量高效,适合简单读写数据,但样式支持有限。 - **Handsontable**:功能强大,提供类Excel在线编辑体验,但商用需付费且性能消耗较大。 - **ExcelJS**:现代全能,API友好,支持复杂样式与公式,免费开源,推荐用于精细处理场景。
487 0
搞定 XLSX 预览?别瞎找了,这几个库(尤其最后一个)真香!