RxJS 操作符详解
操作符是 RxJS 的精髓,它们是纯函数,接收一个 Observable,返回一个新的 Observable,而不会修改原始的 Observable。这种设计使得操作符可以被安全地、声明式地组合。
Pipeable Operators (可管道操作符)
从 RxJS 5.5 开始,引入"可管道操作符"的概念,这是目前使用操作符的标准方式。你通过 Observable.pipe() 方法来使用它们。
typescript
import { from } from 'rxjs';
import { filter, map } from 'rxjs/operators';
const source$ = from([1, 2, 3, 4, 5]);
const result$ = source$.pipe(
filter(x => x % 2 === 0),
map(x => x * 10)
);
result$.subscribe(x => console.log(x)); // 20, 40为什么使用 pipe()?
- 更好的摇树优化 (Tree-shaking): 只导入你需要的操作符,打包工具(如 Webpack, Rollup)可以更容易地移除未使用的代码,减小最终的包体积。
- 更好的代码可读性:
pipe函数将一系列操作以一种线性的、从上到下的方式组合起来,比之前的链式调用 (.filter().map()) 更易读。 - 更好的类型推断: TypeScript 可以更好地推断
pipe中每一步的类型。 - 自定义操作符的组合:
pipe让组合自定义操作符和官方操作符变得非常简单。
操作符的分类
理解操作符的分类有助于我们更好地选择和使用它们。
创建 (Creation) 操作符: 从各种来源创建 Observable。例如
of,from,interval,fromEvent,ajax。转换 (Transformation) 操作符: 转换流中的数据。这是最常用的一类。
map,pluck: 对每个值进行一对一的转换。scan,reduce: 对流进行聚合计算。switchMap,mergeMap,concatMap,exhaustMap: 将一个高阶 Observable "拍平",处理嵌套的异步操作。这是 RxJS 的一个核心和难点。
过滤 (Filtering) 操作符: 从流中筛选出需要的值。
filter,take,skip,first,lastdebounceTime,throttleTime,distinctUntilChanged: 处理用户输入、性能优化的利器。
组合 (Combination) 操作符: 将多个 Observable 合并成一个。
combineLatest,zip: 当你需要合并来自不同流的最新值时使用。merge,concat: 将多个流按时间顺序或先后顺序合并。forkJoin: 类似于Promise.all,等待所有流完成后一次性发出所有流的最后一个值。
错误处理 (Error Handling) 操作符: 优雅地处理流中的错误。
catchError: 捕获错误并提供一个替代的 Observable。retry,retryWhen: 在失败时进行重试。
工具 (Utility) 操作符: 提供一些辅助功能。
tap: 执行副作用(如 logging),不影响流。delay,timeout: 延迟或设置超时。finalize: 在流完成或错误时执行清理工作。
多播 (Multicasting) 操作符: 将单播的 Observable 转换为多播。
share,shareReplay: 共享订阅,避免重复执行。

