RxJS中Hot与Cold Observable操作符有哪些?如何区分?
RxJS Hot 与 Cold Observable 操作符参考核对清单
不存在能直接标记Hot/Cold属性的操作符,冷热本质是Observable实例的生产者运行逻辑决定的,以下是日常开发中高频操作符的默认行为归类,可直接用于核对。
默认返回 Cold Observable 的常见操作符
Cold核心特征:订阅动作才会触发生产者创建,每个订阅者持有独立的生产者实例,不同订阅之间不共享运行状态
- 基础创建类:
of、from(非事件/已存在数据源场景)、new Observable()(即原Observable.create)、defer、interval、timer、ajax、fromFetch、generate - 普通转换/过滤/组合类:
map、filter、concatMap、mergeMap、switchMap、exhaustMap、take、skip、reduce、scan、startWith、concat、merge(无多播逻辑时)
这类操作符的共性:只要上游源是Cold,且链路中没有插入多播类操作符,输出的Observable一定是Cold,新订阅会重新执行完整的流逻辑,触发独立副作用(比如重新发HTTP请求、重新启动独立计时器)。
默认返回 Hot Observable 的常见操作符
Hot核心特征:生产者创建不依赖订阅动作,多个订阅者默认共享同一个生产者实例,订阅前发出的值默认不会被新订阅者收到(除非有缓存配置)
- 基础创建类:
fromEvent、fromEventPattern、webSocket(连接建立逻辑独立于单个订阅时) - Subject类实例:
Subject、BehaviorSubject、ReplaySubject、AsyncSubject(所有Subject本身都是Hot实现,可以在任意订阅外向其推送值) - 多播转换类:
share、shareReplay、publish、publishBehavior、publishReplay、publishLast、multicast、refCount
这类操作符的共性:会把上游的流做共享处理,新订阅不会重新创建上游生产者,而是直接接入已有的运行中的流,订阅者之间共享推送的值。
快速核对方法
不用死记操作符清单,做两个小测试就能100%判定类型:
- 给同一个Observable加两个相隔几秒的订阅,看副作用执行次数:如果执行了2次(比如发了2次请求、启动了2个独立计时器)就是Cold;如果只执行1次就是Hot
- 在订阅前手动给流推送一个值(如果是可手动推送的类型),如果订阅后能收到这个值就是Hot,收不到就是Cold
注意:冷热是Observable实例的运行时特征,不是操作符的固定属性,比如你把
fromEvent包在defer里做延迟绑定、取消订阅就完全销毁生产者,也可以实现Cold的行为,清单只是常规场景下的快速参考。
内容的提问来源于stack exchange,提问作者Eli
相关产品推荐
相关产品推荐

