Angular Subject和BehaviorSubject之间的区别

Subject和BehaviorSubject是RxJS中两种常用的Subject类型。

概念:

  1. Subject:

    • Subject是一种特殊的Observable,同时也是Observer。它可以被用来订阅Observable,也可以手动向它推送新的值。
    • Subject是一种热Observable,它会在订阅时开始推送值,而不管它们何时被推送。
    • Subject不会缓存最新的值,新的订阅者只能接收到订阅后推送的值,而无法获取之前推送的值。
    • Subject适用于需要将事件转换为Observable的场景,或者在多个订阅者之间共享相同的Observable。
  2. BehaviorSubject:

    • BehaviorSubject是一种特殊的Subject,它会缓存最新的值,并在有新的订阅者订阅时立即发送这个最新值给订阅者。
    • BehaviorSubject需要一个初始值作为参数,在没有收到任何值时会发送这个初始值给订阅者。
    • BehaviorSubject适用于需要保存当前状态并让新订阅者立即获取到最新状态的场景。
    • BehaviorSubject常用于管理应用程序的状态,例如全局的用户身份验证状态、主题颜色等。

区别:

  1. 初始值:

    • Subject在创建时不需要指定初始值,而且第一个订阅者只会收到Subject之后调用next()方法推送的值。
    • BehaviorSubject在创建时需要指定一个初始值,这个初始值会立即发送给所有订阅者,无需等待调用next()方法。
  2. 订阅时机:

    • 对于Subject,如果订阅发生在next()方法之后,订阅者将不会收到之前已经通过next()方法推送的值。
    • 对于BehaviorSubject,无论订阅发生在何时,订阅者都会立即收到最新的值,包括初始值和之后通过next()方法推送的值。
  3. 缓存最新值:

    • Subject不会缓存最新的值,每次调用next()方法都会向所有订阅者发送新值。
    • BehaviorSubject会保存最新推送的值,无论是通过next()方法推送的值还是初始值,并在有新订阅者订阅时立即发送这个最新值给订阅者。
    • 当有新的订阅者订阅BehaviorSubject时,它会立即收到缓存的最新值,即使之前已经有值被推送过,而不是等待下一次值的推送。

示例:

两者明显的区别在于Subject不会缓存最新的值,而BehaviorSubject会缓存最新的值,并在有新的订阅者订阅时立即发送这个最新值给订阅者。下面是有关详细说明这两者之间的区别的代码示例:

  • 首先,我们创建一个Subject和一个BehaviorSubject,并分别订阅它们:
javascript 复制代码
import { Subject, BehaviorSubject } from 'rxjs';

// 创建一个 Subject
const subject = new Subject<number>();

// 创建一个 BehaviorSubject,初始值为0
const behaviorSubject = new BehaviorSubject<number>(0);

// 订阅 Subject
subject.subscribe(value => console.log('Subject Subscription:', value));

// 订阅 BehaviorSubject
behaviorSubject.subscribe(value => console.log('BehaviorSubject Subscription:', value));
  • 接下来,我们分别向Subject和BehaviorSubject推送值,并再次订阅它们:
javascript 复制代码
// 向 Subject 推送值
subject.next(1);

// 向 BehaviorSubject 推送值
behaviorSubject.next(1);

// 再次订阅 Subject
subject.subscribe(value => console.log('Subject Subscription 2:', value));

// 再次订阅 BehaviorSubject
behaviorSubject.subscribe(value => console.log('BehaviorSubject Subscription 2:', value));
  • 运行以上代码后,我们可以看到以下输出:
javascript 复制代码
Subject Subscription: 1
BehaviorSubject Subscription: 0
BehaviorSubject Subscription: 1
Subject Subscription 2: 1
BehaviorSubject Subscription 2: 1

示例总结:

上面的示例很好的说明了它们最明显的区别:**会不会缓存最新的值。**什么叫会缓存最新的值呢?

简单来说就是:

缓存最新值就是保存了最新值的意思,也就是说BehaviorSubject 从它订阅开始就一定会收到值,要不就是初始值,要不就是最新一次的next()方法的传递的值。换句话说,BehaviorSubject从订阅开始就会向订阅者发送值,确保订阅者能够获取到初始值或者最新值。但是Subject对象是收到从它订阅开始之后next()传递的最新值,订阅时不会收到任何值!

误区:

对于BehaviorSubject对象,每次调用next()方法,Observer只会收到一个新的值,不会重复收到之前的值,也就是不会累积之前的值,因为它缓存的是最新的值,并不是缓存所有值!

举例说明:

javascript 复制代码
import { BehaviorSubject } from 'rxjs';

const behaviorSubject = new BehaviorSubject<number>(0);

// Observer在BehaviorSubject初始化时订阅
behaviorSubject.subscribe(value => console.log('Observer 1:', value));

// 调用next()方法传递新值
behaviorSubject.next(1);

// Observer再次订阅
behaviorSubject.subscribe(value => console.log('Observer 2:', value));

// 再次调用next()方法传递新值
behaviorSubject.next(2);



//运行以上代码后,我们可以看到以下输出:
Observer 1: 0
Observer 1: 1
Observer 2: 1
Observer 1: 2
Observer 2: 2
相关推荐
小poop5 小时前
CSS 基础与实战:从入门到精通网页美化
前端
Csvn7 小时前
运行时性能
前端
Never_every998 小时前
位图转矢量工具哪个好?实测抠抠图AI位图转矢量工具
大数据·前端
paopaokaka_luck8 小时前
宠物门店经营管理系统(销售与库存联动、进货自动记账、 退换与退款关联、员工个人业绩、ECharts 经营分析、滞销识别与客户分层、宠物档案年龄计算)
前端·javascript·spring boot·mysql·echarts·mybatis·1024程序员节
空中湖9 小时前
用 React 写数据大屏:为什么我不建议用图表库
前端·react.js·前端框架
欣欣之王来了10 小时前
原始HTML插值:v-html指令的使用与安全风险
前端·学习·架构·项目·vue3教程
IT_陈寒10 小时前
Redis的LRU淘汰策略坑了我一整天
前端·人工智能·后端
计算机魔术师10 小时前
砍半价格、参数再涨,国产旗舰追到 Opus 鼻尖了
前端
特立独行的猫A11 小时前
10 MB 的桌面 AI 客户端:用仓颉 + 系统 WebView 替代 Electron
前端·harmonyos
修炼的dance12 小时前
白底图存JPG,sharp开mozjpeg背景杂点少近三成
前端