PublishSubject、ReplaySubject、BehaviorSubject、AsyncSubject的区别

news2025/6/9 13:20:15

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

pyrx安装命令: pip install rx

一、Subject(相当于 RxJava 的 PublishSubject

PublishSubject

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

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

特性

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

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

示例代码
from rx.subject import Subject

subject = 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 ReplaySubject

subject = 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 BehaviorSubject

subject = 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 AsyncSubject

subject = 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个数据管道之间的代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2405403.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在Ubuntu22.04 系统中安装Docker详细教程

1.更新系统软件包 #确保您的系统软件包是最新的。这有助于避免安装过程中可能遇到的问题 sudo apt update sudo apt upgrade -y2.安装必要的依赖 sudo apt install apt-transport-https ca-certificates curl software-properties-common -y3.替换软件源 echo "deb htt…

AUTOSAR实战教程--DoIP_01_配置项解释

配置项 解释 备注 DoIPChannelSARef 引用DoIP Tester的源地址,就是你在DoIP Tester这个Containter中配置的Tester实例。 DoIPChannelTARef 引用目标地址。就是你在DoIPTargetAddress这个Container中的配置。 DoIPPduRRxPduId 为该pdu设置一个ID用于DoIP…

机器人/智能车纯视觉巡线经典策略—滑动窗口+直方图法

作者:SkyXZ CSDN:SkyXZ~-CSDN博客 博客园:SkyXZ - 博客园 在机器人或智能车的自主导航任务中,视觉巡线是一项最为基础且关键的能力之一。通过摄像头实时获取道路图像,并基于图像信息判断行驶路径&#xff0…

503 Service Unavailable:服务器暂时无法处理请求,可能是超载或维护中如何处理?

处理 "503 Service Unavailable" 错误是服务器管理者面临的常见挑战之一。这种错误通常表示服务器暂时无法处理请求,可能是由于服务器超载、维护中或其他临时性问题导致的。在本文中,我将介绍如何处理 "503 Service Unavailable" 错…

虚拟机时间同步

一、常见同步方式 常见的虚拟机同步方式有给虚拟机配置ntp、或者用平台提供的agent对时与虚拟机所在的宿主机。第一种依赖网络、第二种依赖平台的agent这个三方工具。 二、利用ptp_kvm.ko来直接和宿主机同步时间 关键组件 ptp_kvm驱动、chrony。 PTP_KVM同步原理 |--------…

软件更新机制的测试要点与稳定性提升

💗博主介绍💗:✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示:文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…

LLMs 系列科普文(11)

目前我们已经介绍了大语言模型训练的两个主要阶段。第一阶段被称为预训练阶段,主要是基于互联网文档进行训练。当你用互联网文档训练一个语言模型时,得到的就是所谓的 base 模型,它本质上就是一个互联网文档模拟器,我们发现这是个…

10万QPS高并发请求,如何防止重复下单

1. 前端拦截 首先因为是10万QPS的高并发请求,我们要保护好系统,那就是尽可能减少用户无效请求。 1.1 按钮置灰 很多用户抢票、抢购、抢红包等时候,为了提高抢中的概率,都是疯狂点击按钮。会触发多次请求,导致重复下…

Xilinx IP 解析之 Block Memory Generator v8.4 ——02-如何配置 IP(仅 Native 接口)

相关文章: Xilinx IP 解析之 Block Memory Generator v8.4 ——01-手册重点解读(仅Native RAM) – 徐晓康的博客 Xilinx IP 解析之 Block Memory Generator v8.4 ——02-如何配置 IP(仅 Native RAM) – 徐晓康的博客 V…

什么是高考?高考的意义是啥?

能见到这个文章的群体,应该都经历过高考,突然想起“什么是高考?意义何在?” 一、高考的定义与核心功能 **高考(普通高等学校招生全国统一考试)**是中国教育体系的核心选拔性考试,旨在为高校选拔…

Spring Cloud 多机部署与负载均衡实战详解

🧱 一、引言 为什么需要多机部署? 解决单节点性能瓶颈,提升系统可用性和吞吐量 在传统单机部署模式下,系统的所有服务或应用都运行在单一服务器上。这种模式在小型项目或低并发场景中可能足够,但随着业务规模扩大、用…

基于定制开发开源AI智能名片S2B2C商城小程序的首屏组件优化策略研究

摘要:在数字化转型背景下,用户对首屏交互效率的诉求日益提升。本文以"定制开发开源AI智能名片S2B2C商城小程序"为技术载体,结合用户行为数据与认知心理学原理,提出首屏组件动态布局模型。通过分析搜索栏、扫码入口、个人…

EasyRTC嵌入式音视频通信SDK音视频功能驱动视频业务多场景应用

一、方案背景​ 随着互联网技术快速发展,视频应用成为主流内容消费方式。用户需求已从高清流畅升级为实时互动,EasyRTC作为高性能实时音视频框架,凭借低延迟、跨平台等特性,有效满足市场对多元化视频服务的需求。 二、EasyRTC技术…

linux下gpio控制

linux下gpio控制 文章目录 linux下gpio控制1.中断命令控制/sys/class/gpio/export终端命令控制led 2.应用程序控制 3.驱动代码控制 1.中断命令控制 通用GPIO主要用于产生输出信号和捕捉输入信号。每组GPIO均可以配置为输出输入以及特定的复用功能。 当作为输入时,内…

Spring Boot 从Socket 到Netty网络编程(下):Netty基本开发与改进【心跳、粘包与拆包、闲置连接】

上一篇:《Spring Boot 从Socket 到Netty网络编程(上):SOCKET 基本开发(BIO)与改进(NIO)》 前言 前文中我们简单介绍了基于Socket的BIO(阻塞式)与NIO(非阻塞式&#xff0…

Orthanc:轻量级PACS服务器与DICOMweb支持的技术详解

🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C++, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C++、C#等开发语言,熟悉Java常用开发技术,能熟练应用常用数据库SQL server,Oracle,mysql,postgresql等进行开发应用…

量子计算导论课程设计 之 PennyLane环境搭建

文章目录 具体配置conda 虚拟环境配置Pennylane 正所谓,磨刀不误砍柴工,想要进行量子计算导论的课程设计,首先就是搭建好平台,推荐大家就是本地搭建,那么下面有三种选择 QiskitTensorFlow QuantumPennylane 具体配置…

GAN优化与改进:从条件生成到训练稳定性

摘要 本文聚焦生成对抗网络(GAN)的核心优化技术与改进模型。系统解析 条件生成对抗网络(CGAN) 的可控生成机制、深度卷积GAN(DCGAN) 的架构创新,揭示GAN训练崩溃的本质原因,并介绍W…

linux库(AI回答)

STL POSIX关系 DeepSeek-R1 回答完成 搜索全网22篇资料 STL(标准模板库)和 POSIX(可移植操作系统接口)是两种不同领域的技术标准,它们在 C/C 开发中各有侧重,但可以协同使用。以下是它们的关系和区别&…

CoordConv: CNN坐标感知特征适应

传统卷积 vs CoordConv 详细对比 传统卷积对空间位置不敏感,CoordConv通过显式添加坐标信息解决这个问题在特征图中嵌入(x, y)坐标和可选的径向距离r使模型能够感知空间位置关系 1. 传统卷积的"空间位置不敏感"问题 传统卷积的特点: 输入: …