TypeScript中的Subject与BehaviorSubject:主要区别

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Subject与BehaviorSubject:响应式编程世界中的一对“杂技兄弟”



如果你曾经在Stack Overflow上看到过关于“What is the difference between Subject and BehaviorSubject?”的讨论,你就会知道:这个话题吸引了成千上万的浏览量。这并不奇怪——这是每个使用TypeScript进行RxJS开发的开发者迟早都会遇到的问题。



想象一下,你正在管理一个实时数据流。Subject就像一个开放麦克风:谁先订阅,谁就能听到之后说的所有内容。而BehaviorSubject则像一个始终记住最后一句话的麦克风,它会立即把最后一句话重复给新来的听众。你感受到区别了吗?



在本文中,我们不仅仅是复述文档。我们将分析真实案例,展示TypeScript代码示例,并给出清晰的选择规则。让我们开始吧!



TypeScript中的Subject是什么?



Subject是一种特殊的Observable,它同时也是一个观察者(Observer)。它可以通过next()方法接收数据,并将其分发给所有订阅者。但有一个重要的细节:Subject不存储之前的值。



一个简单的TypeScript示例:



import { Subject } from 'rxjs';

const subject = new Subject<string>();

// 在数据发送之后才订阅subject.next('第一条消息');subject.next('第二条消息');

// 这个订阅者什么也收不到subject.subscribe({ next: (value) => console.log('订阅者:', value)});

// 但这条消息可以看到subject.next('第三条消息');


控制台会输出什么?只有“订阅者: 第三条消息”。前两条消息对这个订阅者来说永远丢失了。这种效果被称为“冷启动”——你只能收到订阅之后发送的数据。



BehaviorSubject:当需要记住过去时



BehaviorSubject与Subject类似,但它有一个超能力:它始终存储最后一个值,并在新订阅者订阅时立即将其发送给订阅者。一个必要条件——必须指定一个初始值。



import { BehaviorSubject } from 'rxjs';

const behaviorSubject = new BehaviorSubject<string>('初始值');

// 订阅——立即收到最后一个值behaviorSubject.subscribe({ next: (value) => console.log('第一个订阅者:', value)});

behaviorSubject.next('第一次更新');behaviorSubject.next('第二次更新');

// 这个订阅者会立即收到'第二次更新'behaviorSubject.subscribe({ next: (value) => console.log('第二个订阅者:', value)});


控制台输出:

第一个订阅者: 初始值第一个订阅者: 第一次更新第一个订阅者: 第二次更新第二个订阅者: 第二次更新


看到了吗?第二个订阅者虽然订阅得晚,但立即收到了最后一个值。这是BehaviorSubject与Subject的关键区别。



Subject与BehaviorSubject对比:区别表格



让我们将所有区别汇总到一个直观的表格中,这对你在面试或实际项目中会很有用。



  • 初始值: Subject — 没有。BehaviorSubject — 必须提供。
  • 存储最后一个值: Subject — 不存储。BehaviorSubject — 存储并发送给新订阅者。
  • 延迟订阅时的行为: Subject — 跳过所有之前的事件。BehaviorSubject — 发送最后一个值。
  • 在Angular中的使用: Subject — 用于事件(点击、定时器)。BehaviorSubject — 用于状态(用户数据、设置)。
  • getValue()方法: Subject — 没有。BehaviorSubject — 有,同步返回当前值。


何时使用Subject,何时使用BehaviorSubject

博客

书籍推荐