章节摘要:算子组合是响应式的「设计模式语言」——冷/热流决定订阅语义,
flatMap/switchMap决定并发与取消,错误算子决定故障传播路径,生命周期管理决定资源泄漏与否。
| 节 | 主题 |
|---|---|
| 5.1 | 冷流 vs 热流、share/cache |
| 5.2 | map、flatMap、switchMap、merge |
| 5.3 | onErrorResume、retryWhen |
| 5.4 | Disposable、using、doFinally |
响应式设计模式与传统 GoF 模式的最大区别:每个「模式」对应一个算子组合,而算子的选择就是并发与取消语义的选择。 本章的阅读线索是三条轴:
share() 还是 cache()。flatMap 并发展开、switchMap 取消旧任务、concatMap 保序串行——选错语义 = 并发失控或结果错序。onErrorReturn/onErrorResume/retryWhen 把「故障策略」写成流上可见的代码。三条轴共同回答同一个工程问题:在一个元素、任务、错误都以「流」形式流动的世界里,如何用组合表达清晰的系统行为。
retryWhen 写出带退避与上限的重试策略,并解释为什么裸 retry() 危险第 5 章是第 2 章机制(信号、背压、调度)的组合层:flatMap 的并发度、switchMap 的取消、retryWhen 的重试间隔,全部依赖第 2 章的 Scheduler 与背压机制实现。同时,本章的模式将在第 6 章接受工程检验——反模式清单(6.4)里一半以上的坑,都是「选错了算子语义」或「误用了冷热流」。建议把第 5 章当操作手册读,遇到实际需求时回来查表选算子。
把三节的模式浓缩成一张决策表,遇到实际问题时按「特征 → 模式 → 算子」三层定位:
| 需求特征 | 设计模式 | 核心算子/API |
|---|---|---|
| 同一数据源多订阅 | 热流共享 | share() / publish().refCount() |
| 晚订者要历史数据 | 带缓存热流 | cache() / replay(n) |
| 每订独立执行 | 冷流 | defer() / Mono |
| 同步变换 | 映射模式 | map |
| 并行独立任务 | 展开模式 | flatMap(fn, n) |
| 只留最新 | 切换模式 | switchMap |
| 严格保序 | 串行模式 | concatMap |
| 多源对齐 | 汇合模式 | zip / combineLatest |
| 暂时失败 | 重试模式 | retryWhen(Retry.backoff(...)) |
| 持续失败 | 熔断模式 | CircuitBreakerOperator |
| 彻底降级 | 恢复模式 | onErrorResume / onErrorReturn |
这张速查表是本章的「最终交付物」——建议打印或收藏,编码时随时对照。第五章的教学目的不是让你记住每个算子,而是建立「先想清需求特征,再选算子」的反射。
编码前先回答三个问题:
flatMap/concatMap/switchMap。这三个问题几乎覆盖了日常 80% 的响应式编码决策。把它写进团队的编码规范,比任何代码评审都有用。