React编程高级主题:错误处理(Error Handling)

news2025/4/5 21:43:27

在这里插入图片描述

文章目录

    • **5.2 错误处理(Error Handling)概述**
    • **5.2.1 `onErrorReturn` / `onErrorResume`(错误回退)**
      • **1. `onErrorReturn`:提供默认值**
      • **2. `onErrorResume`:切换备用数据流**
    • **5.2.2 `retry` / `retryWhen`(错误重试)**
      • **1. `retry`:固定次数重试**
      • **2. `retryWhen`:高级条件重试**
    • **5.3 错误处理策略对比**
    • **5.4 总结**
      • **错误回退(Fallback)**
      • **错误重试(Retry)**
      • **最佳实践**

在这里插入图片描述

5.2 错误处理(Error Handling)概述

React + RxJS/Reactive Programming 生态中,数据流(Stream)可能会因 网络错误、API 异常、数据处理失败 等原因抛出错误。如果未正确处理,错误可能导致整个数据流终止,影响用户体验。

错误处理的核心目标

  1. 防止错误导致整个应用崩溃(Graceful Degradation)。
  2. 提供合理的错误恢复机制(Retry/Fallback)。
  3. 记录错误信息(Logging & Monitoring)。

React 生态中常见的错误处理方式包括:

  • onErrorReturn / onErrorResume(错误回退)
  • retry / retryWhen(错误重试)

接下来,我们将深入探讨这些方法的 原理、实现方式及适用场景


在这里插入图片描述

5.2.1 onErrorReturn / onErrorResume(错误回退)

1. onErrorReturn:提供默认值

核心思想:当数据流发生错误时,返回一个 默认值 替代错误,使流继续执行。

适用场景

  • 适用于 可预测的错误(如 API 404 返回默认数据)。
  • 不希望错误中断数据流,但可以接受降级数据。

示例(RxJS)

import { of, throwError } from 'rxjs';
import { onErrorReturn } from 'rxjs/operators';

const source$ = throwError(new Error('API Failed')); // 模拟错误

source$
  .pipe(
    onErrorReturn(() => ({ data: 'Default Value' })) // 错误时返回默认值
  )
  .subscribe({
    next: (val) => console.log('Received:', val), // 输出: Received: { data: 'Default Value' }
    error: (err) => console.error('Error:', err), // 不会触发
  });

底层原理

  • onErrorReturn 会在 error 发生时拦截错误,并调用回调函数返回一个默认值。
  • 该操作符会 终止原 Observable,并返回一个新的 Observable,发射默认值后 complete

在这里插入图片描述

2. onErrorResume:切换备用数据流

核心思想:当主数据流失败时,切换到备用数据流(Fallback Stream)。

适用场景

  • 主 API 失败时,回退到缓存/备用 API。
  • 多数据源冗余设计(如 CDN 回源)。

示例(RxJS)

import { of, throwError } from 'rxjs';
import { onErrorResumeWith } from 'rxjs/operators';

const mainApi$ = throwError(new Error('Main API Down'));
const fallbackApi$ = of({ data: 'Fallback Data' });

mainApi$
  .pipe(
    onErrorResumeWith(fallbackApi$) // 主API失败时切换到备用流
  )
  .subscribe({
    next: (val) => console.log('Received:', val), // 输出: Received: { data: 'Fallback Data' }
    error: (err) => console.error('Error:', err), // 不会触发
  });

底层原理

  • onErrorResumeWith 会在错误发生时 取消订阅原 Observable,并立即订阅备用 Observable。
  • 如果备用流也失败,错误会继续传播(除非嵌套使用多个 onErrorResumeWith)。

在这里插入图片描述

5.2.2 retry / retryWhen(错误重试)

1. retry:固定次数重试

核心思想:在发生错误时,自动重新订阅数据流(可设定最大重试次数)。

适用场景

  • 临时性错误(如网络抖动、API 限流)。
  • 需要 简单重试逻辑 的场景。

示例(RxJS)

import { throwError, timer } from 'rxjs';
import { retry } from 'rxjs/operators';

let attempts = 0;
const flakyApi$ = new Observable((subscriber) => {
  attempts++;
  if (attempts < 3) {
    subscriber.error(new Error('API Failed')); // 前两次模拟失败
  } else {
    subscriber.next('Success on attempt ' + attempts);
    subscriber.complete();
  }
});

flakyApi$
  .pipe(
    retry(2) // 最多重试2次(共3次尝试)
  )
  .subscribe({
    next: (val) => console.log('Received:', val), // 输出: Received: Success on attempt 3
    error: (err) => console.error('Error:', err), // 如果第3次仍失败,会触发
  });

底层原理

  • retry(n) 会在每次错误时重新订阅源 Observable,最多 n 次。
  • 如果所有重试均失败,错误会传递给 Subscriber

在这里插入图片描述

2. retryWhen:高级条件重试

核心思想:通过 自定义逻辑控制重试策略(如指数退避、依赖条件重试)。

适用场景

  • 复杂重试策略(如指数退避、Token 刷新后重试)。
  • 需要 动态调整重试行为(如根据错误类型决定是否重试)。

示例(RxJS:指数退避)

import { throwError, timer } from 'rxjs';
import { retryWhen, mergeMap, delay } from 'rxjs/operators';

const flakyApi$ = throwError(new Error('API Failed'));

flakyApi$
  .pipe(
    retryWhen((errors) =>
      errors.pipe(
        mergeMap((err, attempt) => {
          if (attempt >= 3) {
            return throwError(err); // 超过3次后放弃
          }
          const delayMs = 1000 * 2 ** attempt; // 指数退避:1s, 2s, 4s...
          console.log(`Retry in ${delayMs}ms`);
          return timer(delayMs); // 延迟后重试
        })
      )
    )
  )
  .subscribe({
    next: (val) => console.log('Received:', val),
    error: (err) => console.error('Final Error:', err), // 输出: Final Error: Error: API Failed
  });

在这里插入图片描述
底层原理

  1. retryWhen 接收一个 Observable<Error>,允许自定义重试逻辑。
  2. 每次错误时,可以:
    • 返回 Observable 延迟重试(如 timer)。
    • 返回 throwError 终止重试。
  3. 适用于 Token 刷新后重试
    retryWhen((errors) =>
      errors.pipe(
        mergeMap((err) => {
          if (isTokenExpired(err)) {
            return refreshToken().pipe( // 先刷新Token
              mergeMap(() => timer(1000)) // 再延迟重试
            );
          }
          return throwError(err); // 非Token错误直接抛出
        })
      )
    )
    

在这里插入图片描述

5.3 错误处理策略对比

方法适用场景优点缺点
onErrorReturn提供默认值(如空数据、占位图)简单易用,确保流不中断无法恢复真实数据
onErrorResume切换到备用数据源(如缓存/冗余API)支持多数据源冗余备用数据可能不一致
retry临时性错误(如网络抖动)自动重试,减少手动处理可能加重服务器负载(无限重试时)
retryWhen复杂重试逻辑(如指数退避、Token刷新)灵活控制重试策略实现复杂度较高

5.4 总结

错误回退(Fallback)

  • onErrorReturn:适合静态降级(如默认值)。
  • onErrorResume:适合动态降级(如备用API)。

错误重试(Retry)

  • retry(n):适合简单重试(固定次数)。
  • retryWhen:适合高级策略(指数退避、条件重试)。
    在这里插入图片描述

最佳实践

  1. 关键数据:优先使用 retryWhen + onErrorResume 保证可用性。
  2. 非关键数据:使用 onErrorReturn 快速降级。
  3. 监控所有错误:在 subscribeerror 回调中记录日志。

通过合理组合这些策略,可以构建 健壮、可恢复的 React 数据流应用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2328801.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ubuntu20.04升级成ubuntu22.04

命令行 sudo do-release-upgrade 我是按提示输入y确认操作&#xff0c;也可以遇到配置文件冲突时建议选择N保留当前配置

SpringCloud(25)——Stream介绍

1.场景描述 当我们的分布式系统建设到一定程度了&#xff0c;或者服务间是通过异步请求来通讯的&#xff0c;那么我们避免不了使用MQ来解决问题。 假如公司内部进行了业务合并或者整合&#xff0c;需要服务A和服务B通过MQ的方式进行消息传递&#xff0c;而服务A用的是RabbitMQ&…

centos8上实现lvs集群负载均衡dr模式

1.前言 个人备忘笔记&#xff0c;欢迎探讨。 centos8上实现lvs集群负载均衡nat模式 centos8上实现lvs集群负载均衡dr模式 之前写过一篇lvs-nat模式。实验起来相对顺利。dr模式最大特点是响应报文不经调度器&#xff0c;而是直接返回客户机。 dr模式分同网段和不同网段。同…

uniapp如何接入星火大模型

写在前面&#xff1a;最近的ai是真的火啊&#xff0c;琢磨了一下&#xff0c;弄个uniappx的版本开发个东西玩一下&#xff0c;想了想不知道放啥内容&#xff0c;突然觉得deepseek可以接入&#xff0c;好家伙&#xff0c;一对接以后发现这是个付费的玩意&#xff0c;我穷&#x…

MySQL vs MSSQL 对比

在企业数据库管理系统中&#xff0c;MySQL 和 Microsoft SQL Server&#xff08;MSSQL&#xff09;是最受欢迎的两大选择。MySQL 是一款开源的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;由 MySQL AB 开发&#xff0c;现归属于 Oracle 公司。而 MSSQL 是微…

python基础-10-组织文件

文章目录 【README】【10】组织文件&#xff08;复制移动删除重命名&#xff09;【10.1】shutil模块(shell工具)【10.1.1】复制文件和文件夹【10.1.1.1】复制文件夹及其下文件-shutil.copytree 【10.1.2】文件和文件夹的移动与重命名【10.1.3】永久删除文件和文件夹【10.1.4】用…

ORA-09925 No space left on device 问题处理全过程记录

本篇文章关键字&#xff1a;linux、oracle、审计、ORA-09925 一、故障现像 朋友找到我说是他们备份软件上报错。 问题比较明显&#xff0c;ORA-09925&#xff0c;看起来就是空间不足导致的 二、问题分析过程 这里说一下逐步的分析思路&#xff0c;有个意外提前说一下就是我…

多输入多输出 | Matlab实现BO-GRU贝叶斯优化门控循环单元多输入多输出预测

多输入多输出 | Matlab实现BO-GRU贝叶斯优化门控循环单元多输入多输出预测 目录 多输入多输出 | Matlab实现BO-GRU贝叶斯优化门控循环单元多输入多输出预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab实现BO-GRU贝叶斯优化门控循环单元多输入多输出预测&#…

27信号和槽_自定义信号(2)

自定义信号和槽 绑定信号和槽 如何才能触发出自定义的信号呢?&#xff08;上诉代码只是将信号和槽绑定在一起&#xff0c;但并没有触发信号&#xff09; Qt 内置的信号,都不需要咱们手动通过代码来触发 用户在 GUI, 进行某些操作,就会自动触发对应信号.(发射信号的代码已经内置…

人工智能在生物医药领域的应用地图:AIBC2025将于6月在上海召开!

人工智能在生物医药领域的应用地图&#xff1a;AIBC2025将于6月在上海召开&#xff01; 近年来&#xff0c;人工智能在生物医药行业中的应用受到广泛关注。 2024年10月&#xff0c;2024诺贝尔化学奖被授予“计算蛋白质设计和蛋白质结构预测”&#xff0c;这为行业从业人员带来…

2025.3.19

1、用vim编辑/etc/hosts文件&#xff0c;将本机和第二个虚拟机的ip地址和主机名写入该文件&#xff0c;然后ping 两个主机的主机名能否ping通&#xff1b; &#xff08;1&#xff09;在第一个虚拟机编辑/etc/hosts: 首先使用hostname、hostnamectl、hostname -f指令查看主机名…

深度学习 Deep Learning 第16章 结构化概率模型

深度学习 Deep Learning 第16章 结构化概率模型 内容概要 本章深入探讨了结构化概率模型&#xff08;Graphical Models&#xff0c;包含有向图和无向图模型&#xff09;的概念及其在深度学习中的应用。结构化概率模型通过图结构描述随机变量之间的直接交互&#xff0c;从而简…

鸿蒙 harmonyOS 网络请求

应用通过HTTP发起一个数据请求&#xff0c;支持常见的GET、POST、OPTIONS、HEAD、PUT、DELETE、TRACE、CONNECT方法。 接口说明 HTTP数据请求功能主要由http模块提供。 使用该功能需要申请ohos.permission.INTERNET权限。 第一步 &#xff1a; 在module.json5文件里面添加网络…

进程概念(Linux)

目录 一. 冯诺依曼体系结构 二. 操作系统(OS(操作系统的英文缩写Operator System)) 2.1概念 2-2 设计OS的目的 2.3 核心功能 2.4 如何管理&#xff08;先描述再组织&#xff09; 2.5 系统调用和库函数概念 三.进程 3.1 基本概念与基本操作 3.2 描述进程-PCB 3.3 如何…

免费在线MBTI性格测试工具 - 探索你的性格特质

免费在线MBTI性格测试工具 - 探索你的性格特质 简介 我很高兴为大家分享这个专业的MBTI性格测试工具。这是一个完全免费的在线测试系统&#xff0c;基于迈尔斯-布里格斯类型指标(MBTI)理论开发&#xff0c;旨在帮助您更好地了解自己的性格特征&#xff0c;发现职业发展方向。…

AI 数理逻辑基础之统计学基本原理(上)

目录 文章目录 目录统计学统计学基本概念描述性统计数据可视化图表工具 汇总统计统计数据的分布情况&#xff1a;中位数、众数、平均值统计数据的离散程度&#xff1a;极差、方差、标准差、离散系数 相关分析Pearson 线性关系相关系数Spearman 单调关系相关系数 回归分析回归模…

积分赛——读取实时时间

设计要求 调用DS1302芯片驱动程序&#xff0c;读取DS1302中的实时时分秒数据&#xff0c;并显示在数码管上。 23时59分59秒 通过串口发送时间作为定时时间&#xff0c;定时时间到则蜂鸣器响2s后静音。 串口发送格式&#xff1a;“12&#xff1a;35&#xff1a;66”。 备注&…

进程和线程的概念及Linux操作

文章目录 一、进程与线程1、进程2、线程3、查看进程与线程 二、Linux的“虚拟内存管理”&#xff0c;它与stm32中的 真实物理内存&#xff08;内存映射&#xff09;有什么区别&#xff1f;三、Linux系统调用函数 fork()、wait()、exec() 等1、fork&#xff08;&#xff09;函数…

APang网联科技项目报告【服务器篇】

APang网联科技&#xff1a;连接未来&#xff0c;智能领航 公司简介 APang网联科技成立于 [2005年]&#xff0c;总部位于 [广东深圳]&#xff0c;是一家集网络技术研发、系统集成、项目实施与运维服务为一体的高新技术企业。我们致力于为客户提供全方位、定制化的网络部署解决…

[MySQL初阶]MySQL表的操作

MySQL表的操作 1. 创建表2. 查看表结构3. 修改表&#xff08;修改表的属性而非表的数据&#xff09;4. 删除表 1. 创建表 语法&#xff1a; CREATE TABLE table_name (field1 datatype,field2 datatype,field3 datatype ) character set 字符集 collate 校验规则 engine 存储…