乐闻世界logo
搜索文章和话题

RxJS 中 Subject、BehaviorSubject、ReplaySubject 和 AsyncSubject 有什么区别?

2026年2月21日 16:55

Subject 的核心概念

Subject 是 RxJS 中一种特殊的 Observable,它既是 Observable 又是 Observer。这意味着它可以:

  • 被多个观察者订阅
  • 主动推送新值给所有订阅者
  • 实现多播(multicast)功能

Subject 类型

1. Subject

基础 Subject,每次有新订阅者时,不会回放之前的值

javascript
const subject = new Subject(); subject.next(1); subject.next(2); const subscription1 = subject.subscribe(value => console.log('订阅者1:', value)); // 订阅者1: 3 // 订阅者1: 4 subject.next(3); subject.next(4); const subscription2 = subject.subscribe(value => console.log('订阅者2:', value)); // 订阅者2: 5 // 订阅者2: 6 subject.next(5); subject.next(6);

2. BehaviorSubject

BehaviorSubject 会记住最新的值,新订阅者会立即接收到当前值

javascript
const behaviorSubject = new BehaviorSubject('初始值'); behaviorSubject.subscribe(value => console.log('订阅者1:', value)); // 订阅者1: 初始值 behaviorSubject.next('值1'); // 订阅者1: 值1 behaviorSubject.subscribe(value => console.log('订阅者2:', value)); // 订阅者2: 值1 - 立即收到最新值 behaviorSubject.next('值2'); // 订阅者1: 值2 // 订阅者2: 值2

3. ReplaySubject

ReplaySubject 可以回放指定数量的历史值

javascript
const replaySubject = new ReplaySubject(2); // 回放最后2个值 replaySubject.next('值1'); replaySubject.next('值2'); replaySubject.next('值3'); replaySubject.subscribe(value => console.log('订阅者1:', value)); // 订阅者1: 值2 // 订阅者1: 值3 replaySubject.next('值4'); // 订阅者1: 值4 replaySubject.subscribe(value => console.log('订阅者2:', value)); // 订阅者2: 值3 // 订阅者2: 值4

4. AsyncSubject

AsyncSubject 只在完成时发出最后一个值

javascript
const asyncSubject = new AsyncSubject(); asyncSubject.subscribe(value => console.log('订阅者1:', value)); asyncSubject.next('值1'); asyncSubject.next('值2'); asyncSubject.next('值3'); // 此时还没有输出 asyncSubject.complete(); // 订阅者1: 值3 - 只发出最后一个值 asyncSubject.subscribe(value => console.log('订阅者2:', value)); // 订阅者2: 值3 - 新订阅者也能收到最后一个值

实际应用场景

Subject 使用场景

  • 事件总线
  • 状态管理
  • 多个组件共享数据流

BehaviorSubject 使用场景

  • 存储当前状态
  • 表单状态管理
  • 用户信息管理

ReplaySubject 使用场景

  • 缓存历史数据
  • 重播操作日志
  • 错误重试机制

AsyncSubject 使用场景

  • HTTP 请求缓存
  • 只需要最终结果的计算
  • 异步操作的最后值

与普通 Observable 的区别

javascript
// 普通 Observable - 单播 const observable = new Observable(subscriber => { subscriber.next(1); subscriber.next(2); }); observable.subscribe(v => console.log('观察者1:', v)); observable.subscribe(v => console.log('观察者2:', v)); // 每个订阅者独立执行 // Subject - 多播 const subject = new Subject(); const source = new Observable(subscriber => { subscriber.next(1); subscriber.next(2); }); source.subscribe(subject); subject.subscribe(v => console.log('订阅者1:', v)); subject.subscribe(v => console.log('订阅者2:', v)); // 所有订阅者共享同一个数据流

性能考虑

Subject 在多播场景下可以提高性能,避免重复执行相同的异步操作。但需要注意内存泄漏问题,及时取消订阅。

标签:Rxjs