当前位置: 首页 > news >正文

PublishSubject、ReplaySubject、BehaviorSubject、AsyncSubject的区别

python容易编辑,因此用pyrx代替rxjava3做演示会比较快捷。

pyrx安装命令: pip install rx

一、Subject(相当于 RxJava 的 PublishSubject

PublishSubject

PublishSubject 将对观察者发送订阅后产生的元素,而在订阅前发出的元素将不会发送给观察者。如果你希望观察者接收到所有的元素,你可以通过使用 Observable 的 create 方法来创建 Observable,或者使用 ReplaySubject。

如果源 Observable 因为产生了一个 error 事件而中止, PublishSubject 就不会发出任何元素,而是将这个 error 事件发送出来。

特性

  • 只发送订阅后产生的事件,不保留历史值。
  • 新订阅者只能收到订阅后发射的元素。

适用场景
实时数据流(如用户输入、网络事件)。

示例代码
from rx.subject import Subjectsubject = Subject()# 订阅1在事件发射前订阅
subject.subscribe(on_next=lambda value: print("订阅1:", value),on_error=lambda error: print("错误:", error),on_completed=lambda: print("完成")
)subject.on_next("🐶")  # 订阅1收到: 🐶# 订阅2在事件发射后订阅
subject.subscribe(on_next=lambda value: print("订阅2:", value),on_error=lambda error: print("错误:", error),on_completed=lambda: print("完成")
)subject.on_next("🐱")  # 订阅1收到: 🐱,订阅2收到: 🐱

二、ReplaySubject

ReplaySubject

ReplaySubject 将对观察者发送全部的元素,无论观察者是何时进行订阅的。

这里存在多个版本的 ReplaySubject,有的只会将最新的 n 个元素发送给观察者,有的只会将限制时间段内最新的元素发送给观察者。

如果把 ReplaySubject 当作观察者来使用,注意不要在多个线程调用 onNextonError 或 onCompleted。这样会导致无序调用,将造成意想不到的结果。

特性

  • 缓存所有发射过的事件,新订阅者会收到全部历史事件。
  • 可通过 buffer_size 参数限制缓存数量。

适用场景
需要回放历史数据的场景(如配置变更、初始化数据)。

示例代码
from rx.subject import ReplaySubjectsubject = ReplaySubject(buffer_size=2)  # 只缓存最近2个事件subject.on_next("🐶")
subject.on_next("🐱")
subject.on_next("🐭")# 订阅时会收到缓存的最后2个事件: 🐱, 🐭
subject.subscribe(on_next=lambda value: print("订阅1:", value))subject.on_next("🐹")  # 订阅1收到: 🐹

三、BehaviorSubject

BehaviorSubject

当观察者对 BehaviorSubject 进行订阅时,它会将源 Observable 中最新的元素发送出来(如果不存在最新的元素,就发出默认元素)。然后将随后产生的元素发送出来。

如果源 Observable 因为产生了一个 error 事件而中止, BehaviorSubject 就不会发出任何元素,而是将这个 error 事件发送出来。

特性

  • 缓存最后一个发射的事件,新订阅者会立即收到该值。
  • 创建时必须提供初始值。

适用场景
状态管理(如用户登录状态、系统配置)。

示例代码
from rx.subject import BehaviorSubjectsubject = BehaviorSubject("初始值")subject.on_next("🐶")# 订阅时会收到最后一个值: 🐶
subject.subscribe(on_next=lambda value: print("订阅1:", value))subject.on_next("🐱")  # 订阅1收到: 🐱

四、AsyncSubject

AsyncSubject

AsyncSubject 将在源 Observable 产生完成事件后,发出最后一个元素(仅仅只有最后一个元素),如果源 Observable 没有发出任何元素,只有一个完成事件。那 AsyncSubject 也只有一个完成事件。

它会对随后的观察者发出最终元素。如果源 Observable 因为产生了一个 error 事件而中止, AsyncSubject 就不会发出任何元素,而是将这个 error 事件发送出来。

特性

  • 只发射最后一个事件,且仅在 on_completed() 后发射。
  • 如果未调用 on_completed(),订阅者不会收到任何值。

适用场景
只关心最终结果的场景(如计算完成后的结果)。

示例代码
from rx.subject import AsyncSubjectsubject = AsyncSubject()subject.subscribe(on_next=lambda value: print("订阅1:", value),on_error=lambda error: print("错误:", error),on_completed=lambda: print("完成")
)subject.on_next("🐶")
subject.on_next("🐱")
subject.on_completed()  # 订阅1收到: 🐱(最后一个值)并触发完成

五、对比表格

Subject 类型历史值处理新订阅者行为触发条件
Subject不保留历史值只接收订阅后的事件无特殊条件
ReplaySubject缓存所有或部分历史值接收全部缓存的历史事件无特殊条件
BehaviorSubject缓存最后一个值立即接收最后一个值无特殊条件
AsyncSubject缓存最后一个值仅在 on_completed() 后接收必须调用 on_completed()

六、注意事项

  1. 内存管理
    ReplaySubject 和 BehaviorSubject 会持有历史值,需注意避免内存泄漏。

  2. 线程安全
    RxPY 的 Subject 默认非线程安全,多线程环境下需自行处理同步。

  3. 生命周期管理
    使用 dispose() 方法释放资源,避免不必要的事件处理。

rxjava3具体实例:

在引入rxjava3之前的写法:通过监听器,实现register、unregister,代码逻辑臃肿、结构复杂、过一段时间之后自己写的代码都看起来很费劲。

引入rxjava3之后,activity、fragment、service之间解除了强耦合,代码嵌套深度降低、逻辑交叉点减少,代码清爽很多。

rx是响应式编程框架的集大成者,相当于应用内部的轻量级的ASMQ(高级消息队列),前端是ui和逻辑分离的特点,需要大量的数据双向多层传递。  用rx可以从出发点直达终点,数据不需要层层传递,比如说原来的传递路径是6层,你修改一次数据类,你就需要修改6个地方的代码,用rx只需要修改前后紧挨着的2个数据管道之间的代码。

相关文章:

  • React 第五十四节 Router中useRevalidator的使用详解及案例分析
  • AI智能推荐实战之RunnableParallel并行链
  • Haproxy的基础配置
  • AI问答-vue3+ts+vite:http://www.abc.com:3022/m-abc-pc/#/snow 这样的项目 在服务器怎么部署
  • vue+element-ui一个页面有多个子组件组成。子组件里面有各种表单,实现点击enter实现跳转到下一个表单元素的功能。
  • Excel-vlookup -多条件匹配,返回指定列处的值
  • sanitizer工具
  • 三表查询SQL怎么写?----小白初学+案例引入
  • Compose Multiplatform 实现自定义的系统托盘,解决托盘乱码问题
  • [Java 基础]数组
  • 世事无常,比较复杂,人可以简单一点
  • 钢轨滚动疲劳试验机
  • Spring框架知识体系全面总结
  • 图简记。。
  • 设计模式域——软件设计模式全集
  • 【Web应用】若依框架:基础篇21二次开发-页面调整
  • ceph pool 修改故障域
  • 【java面试】框架篇
  • 前端面试四之Fetch API同步和异步
  • MCP通信方式之Streamable HTTP
  • 温州做网站建设哪家好/seo排名规则
  • 上海金桥建设监理有限公司网站/新型网络营销方式
  • 网站搭建书籍推荐/中国市场营销网
  • 寮步网站制作/目前搜索引擎排名
  • 济南建设网站制作/品牌网络推广运营公司
  • 两个网站 一个域名/aso关键字优化