Subject、BehaviorSubject、ReplaySubject、AsyncSubject、VoidSubject比较

RxJS 中各种 Subject 类型的比较

RxJS 提供了多种 Subject 变体,每种都有不同的特性。以下是主要的 Subject 类型及其比较:

1. Subject

基本特性:

  • 纯粹的发布/订阅模式
  • 不存储任何值
  • 新订阅者只能收到订阅后发出的值

javascript

javascript 复制代码
const subject = new Subject();
subject.subscribe(v => console.log(`A: ${v}`)); // 不会立即收到值

subject.next(1); // A: 1
subject.next(2); // A: 2

subject.subscribe(v => console.log(`B: ${v}`)); // 不会收到之前的值
subject.next(3); // A: 3, B: 3

2. BehaviorSubject

基本特性:

  • 存储"当前"值
  • 新订阅者立即收到最后一个值
  • 必须提供初始值

javascript

css 复制代码
const behaviorSubject = new BehaviorSubject(0);
behaviorSubject.subscribe(v => console.log(`A: ${v}`)); // A: 0

behaviorSubject.next(1); // A: 1
behaviorSubject.next(2); // A: 2

behaviorSubject.subscribe(v => console.log(`B: ${v}`)); // B: 2
behaviorSubject.next(3); // A: 3, B: 3

3. ReplaySubject

基本特性:

  • 可以缓存指定数量的值
  • 新订阅者会收到缓存的所有值
  • 可以设置缓存窗口时间

javascript

ini 复制代码
const replaySubject = new ReplaySubject(2); // 缓存最后2个值
replaySubject.next(1);
replaySubject.next(2);
replaySubject.next(3);

replaySubject.subscribe(v => console.log(`A: ${v}`)); 
// 输出: A: 2, A: 3 (收到最后2个值)

4. AsyncSubject

基本特性:

  • 只在 complete 时发送最后一个值
  • 如果没有值则什么都不发送
  • 新订阅者在 complete 后也会收到最后一个值

javascript

ini 复制代码
const asyncSubject = new AsyncSubject();
asyncSubject.subscribe(v => console.log(`A: ${v}`));

asyncSubject.next(1);
asyncSubject.next(2);
asyncSubject.next(3);

asyncSubject.complete(); // A: 3

5. VoidSubject

基本特性:

  • 专门用于不携带数据的事件通知
  • 只关心事件发生,不关心值

javascript

javascript 复制代码
const voidSubject = new Subject<void>();
voidSubject.subscribe(() => console.log('事件发生了'));
voidSubject.next();

比较表格

特性 Subject BehaviorSubject ReplaySubject AsyncSubject VoidSubject
需要初始值 否 是 否 否 否
存储值 否 最后一个 可配置数量 最后一个 否
新订阅者接收的值 无 最后一个 缓存的所有 完成时的最后 无
完成前发送值 是 是 是 否 是
典型用途 事件总线 状态管理 历史记录 最终结果 无值事件

使用建议

  1. 需要初始状态 → BehaviorSubject
  2. 只需要最新事件 → Subject
  3. 需要历史记录 → ReplaySubject
  4. 只关心最终结果 → AsyncSubject
  5. 无值通知 → VoidSubject

选择哪种 Subject 取决于你的具体需求,特别是关于值存储和新订阅者行为的要求。

相关推荐
风骏时光牛马11 分钟前
生成一个AI开源工具体验标题,只需要一个标题,不需要其他的任何文本。
前端
软件派1 小时前
生产动态数据智能风控:阈值判别、趋势预测、异常识别算法工程落地实战
前端·数据库·算法
花开盛夏^.^10 小时前
电脑打开多个浏览器Web窗口占用较大的运行内存的原因
前端·浏览器
馒头不想说话11 小时前
实体店老板的24小时AI运营员工,写、剪、发全自动,省下一整个团队工资
前端
椒哥13 小时前
一天被问几十次"允许",我统计了 517 次,然后写了个插件
前端·javascript·github
风骏时光牛马13 小时前
生成一个AI稳定性治理及疑难问题分析标题,只需要一个标题,不需要其他的任何文本。
前端
莫西干式秃头13 小时前
用 AI + threejs 写了个浏览器里的 3D 动作游戏《武来》:砍怪、放技能、开 SU7
前端·人工智能·three.js
kyriewen13 小时前
我测了 6 种防请求竞态的写法:只有 1 种真能打
前端·javascript·程序员
孟健13 小时前
用 WorkBuddy 做个人名片网页,挂上开源设计技能后效果完全不同了
前端·人工智能·ai编程
IT_陈寒14 小时前
SpringBoot自动配置的坑,这次终于爬出来了
前端·人工智能·后端