RxJS 库

2024 年 8 月 29 日 | 阅读 6 分钟

响应式编程是一种异步编程范例,用于处理数据流和更改传播。RxJS(JavaScript 的响应式扩展)是一个使用 observable 进行响应式编程的库,它使编写异步或基于回调的代码变得容易。

RxJS 实现 Observable 类型,该类型是必需的,直到该类型成为语言的一部分并且浏览器支持它为止。该库还提供了用于构建 observable 和处理它们的实用函数。这些实用函数可用于

将现有异步操作代码转换为 observable

  • 遍历流中的值
  • 将值映射到不同类型
  • 过滤流
  • 组合多个流
  • Observable 创建函数

RxJS 提供了几个可用于创建新 observable 的函数。这些函数可以简化从事件、定时器和 Promise 等内容创建 observable。例如

从 Promise 创建 observable

创建发出 AJAX 请求的 observable

运算符

Operator 是建立在 observable 基础之上,用于对集合进行复杂操作的函数。例如,RxJS 定义了诸如 map()、filter()、concat() 和 flatmap() 等 operator。

Operator 接受配置选项,并返回一个接受源 observable 的函数。执行此返回的函数时,operator 会查看源 observable 的值,对其进行转换,并返回一个包含这些转换值的新 observable。以下是一个简单的示例

Map operator

您可以使用 pipes 将 operators 组合在一起。Pipes 允许您将多个函数合并为一个函数。pipe() 函数会考虑您想要连接的函数,并返回一个新函数,该函数在执行时按顺序运行创建的函数。

应用于 Observable 的一组 operator 是一个“配方”——也就是说,一组用于生成您感兴趣的值的指令。配方本身什么也不做。您需要调用 subscribe() 来通过配方生成结果。

下面是示例

独立的 pipe 函数

pipe() 函数也是 RxJS Observable 的一个方法,因此您可以使用这种更短的形式来定义相同的操作

Observable.pipe 函数

// 订阅以获取值

常用 operator

RxJS 提供了许多 operator,但只有少数几个经常使用。有关 operator 列表和用法示例,请访问 RxJS API 文档。

请注意,对于 Angular 应用程序,我们更倾向于将 operators 与 pipes 结合使用,而不是链式调用。链式调用在许多 RxJS 示例中都有使用。

AREAOPERATORS
创建from, fromEvent, of
组合 (Combination)combineLatest, concat, merge, startWith, withLatestFrom, zip
过滤debounceTime, distinctUntilChanged, filter, take, takeUntil
转换buffer time, concatMap, map, mergeMap, scan, switch the map
用途tap
多播share

错误处理

除了在订阅时提供的 error() 处理程序之外,RxJS 还提供了 CatchError operator,它允许您在 observable 的“配方”中处理已知错误。

例如,假设您有一个发出 API 请求并映射服务器响应的 observable。如果服务器返回错误或值不存在,则会生成错误。如果您捕获此错误并提供默认值,您的流将继续处理值而不是错误。

以下是使用 catchError operator 执行此操作的示例

重试失败的 observable

catch error operator 提供了一个简单的恢复途径,而 retry operator 则允许您重试失败的请求。

在 catch error operator 之前使用 retry operator。它会重新订阅源 observable,然后可以重播导致错误的整个操作序列。如果其中包含 HTTP 请求,它将重试该 HTTP 请求。

以下是将前面的示例转换为在捕获错误之前重试请求

retry operator

请勿重试身份验证请求,因为这些请求只能由用户操作发起。我们不希望用户账户因用户未发起的重复登录请求而被锁定。

Observable 的命名约定

由于 Angular 应用程序主要使用 TypeScript 编写,因此您通常会知道何时某个变量是 observable。尽管 Angular 框架不强制执行 observable 的命名约定,但您通常会看到以“$”结尾命名的 observable。

这在浏览代码并查找 observable 值时非常有用。此外,如果您希望一个属性存储来自 observable 的最新值,那么使用相同的名称(带或不带“$”)会很方便。

例如

命名 observables


下一主题Angular 9 特性