#介绍

首先,对象关系上,Subject是Observable的子类,相比拥有了多播的效果,使得多个订阅者订阅的对象数据是共享的,而在它下面又细分了AnonymousSubject, AsyncSubject, BehaviorSubject三个子类,分别用于处理不同场景的业务需求。

#Observable和Subject的差异

  • Observable的每个订阅者之间,读取的发布数据是相对各自独立的。
  • Subject的订阅者之间,是共享一个发布数据的。

#Subject的子类详情

1. BehaviorSubject

Subject的主要子类是BehaviorSubject,使用BehaviorSubject具有存储当前“值”的特性,这意味着我们始终可以直接从BehaviorSubject获取最后发出的值。

获取值一共有两种方法

  1. 通过访问.value属性来获取值
  2. 通过订阅BehaviorSubject来获取值,BehaviorSubject将直接向订阅者发出当前值。即使订阅者订阅的时间远远晚于存储的值。
import * as Rx from "rxjs";const subject = new Rx.BehaviorSubject();// 订阅对象1
subject.subscribe((data) => {console.log('Subscriber A:', data);
});
//发布新的值
subject.next(Math.random());
subject.next(Math.random());// 订阅对象2
subject.subscribe((data) => {console.log('Subscriber B:', data);
});
// 再次发布新的值
subject.next(Math.random());console.log(subject.value)// 输出日志
// Subscriber A: 0.24957144215097515
// Subscriber A: 0.8751123892486292
// Subscriber B: 0.8751123892486292
// Subscriber A: 0.1901322109907977
// Subscriber B: 0.1901322109907977
// 0.1901322109907977
  1. 我们首先创建一个主题并使用Subscriber A订阅它。然后,Subject将发出它的值,订阅者A将记录随机数。
  2. 主题发出它的下一个值。订户A将再次记录此信息
  3. 订阅者B从订阅主题开始。由于主题是BehaviorSubject,新订阅者将自动接收最后存储的值并记录此信息。
  4. 主题再次发出新值。现在,两个订阅者都将收到值并记录它们。
  5. 最后,我们只需访问该.value属性即可记录当前的Subjects值  ,因为它是同步的,可以不用通过订阅读取值。

最后,我发现现在已经需要在创建对象的时候赋予初始值,如下示例:

import * as Rx from "rxjs";
// 参数:初始值
const subject = new Rx.BehaviorSubject(Math.random());

2.ReplaySubject

ReplaySubject可以与BehaviorSubject相比,它可以向新订阅者发送“旧”的历史值。借此特性,我们可以用它可以记录可观察对象执行的一部分,因此存储多个旧值并将它们“重放”给新的订阅者。

创建ReplaySubject时,你可以指定要存储的值的数量以及要存储它们的时间长度。

import * as Rx from "rxjs";
// 存储2个值,这些值在新订阅之前的最后一秒执行
const subject = new Rx.ReplaySubject(2);// 开始使用订阅者A订阅主题
subject.subscribe((data) => {console.log('Subscriber A:', data);
});
// 发布三个新值
subject.next(Math.random())
subject.next(Math.random())
subject.next(Math.random())// 订阅B
subject.subscribe((data) => {console.log('Subscriber B:', data);
});
// 发布新值
subject.next(Math.random());// 输出日志
// Subscriber A: 0.3541746356538569
// Subscriber A: 0.12137498878080955
// Subscriber A: 0.531935186034298
// Subscriber B: 0.12137498878080955
// Subscriber B: 0.531935186034298
// Subscriber A: 0.6664809293975393
// Subscriber B: 0.6664809293975393

根据输出来看,订阅者A记录了三个发布值。

由于我们告诉ReplaySubject存储2个值,它将直接向订阅者B发送最后两个值,订阅者B于是只输出了最后发布的两个值。

除此之外,我们还可以指定存储值的时间,如下所示。

import * as Rx from "rxjs";
//创建ReplaySubject并指定只存储最后2个值,但不超过100毫秒
const subject = new Rx.ReplaySubject(2, 100);// 创建订阅A
subject.subscribe((data) => {console.log('Subscriber A:', data);
});
// 每隔200毫秒开始发出主题值。订阅者A将选择此项并记录主题发出的每个值
setInterval(() => subject.next(Math.random()), 200);// 创建订阅B
setTimeout(() => {subject.subscribe((data) => {console.log('Subscriber B:', data);});
}, 1000)// 输出日志
// Subscriber A: 0.44524184251927656
// Subscriber A: 0.5802631630066313
// Subscriber A: 0.9792165506699135
// Subscriber A: 0.3239616040117268
// Subscriber A: 0.6845077617520203
// Subscriber B: 0.6845077617520203
// Subscriber A: 0.41269171141525707
// Subscriber B: 0.41269171141525707
// Subscriber A: 0.8211466186035139
// Subscriber B: 0.8211466186035139

如上所示,我们开始订阅者B后,因为我们在1000毫秒后执行此操作,这意味着在开始订阅之前,主题已经发出了5个值。

这意味着在1000毫秒之后,当订阅者B开始订阅时,它将仅接收1个值,因为主体每200ms发出一次值。

3. AsyncSubject

虽然BehaviorSubject和ReplaySubject都存储值,但AsyncSubject的工作方式略有不同。AsyncSubject是一个主题变体,只有Observable执行的最后一个值才会发送给它的订阅者,并且只有在执行完成时才会发送.

import * as Rx from "rxjs";
// 创建了AsyncSubject
const subject = new Rx.AsyncSubject();// 创建订阅A
subject.subscribe((data) => {console.log('Subscriber A:', data);
});subject.next(Math.random())
subject.next(Math.random())
subject.next(Math.random())// 创建订阅B
subject.subscribe((data) => {console.log('Subscriber B:', data);
});subject.next(Math.random());
subject.complete();// 输出日志
// Subscriber A: 0.4447275989704571
// Subscriber B: 0.4447275989704571

如上我们能够观察到,A并没有输出发布的前三个值,是因为只有当订阅对象complete完成后,才会将值发送给订阅者。

#结论

BehaviorSubject,ReplaySubject和AsyncSubject不仅可以像使用普通Subject一样用于多播,而且它们在不同场景中各自有具有非常方便的特性,我们可以结合业务场景和需求具体使用。

PS: 如上教程多为译文,原文地址如下(可能需要VPN才能访问):

原文:https://medium.com/@luukgruijs/understanding-rxjs-behaviorsubject-replaysubject-and-asyncsubject-8cc061f1cfc0

Observable与Subject相关推荐

  1. RXJS 中 Observable 和 Subject

    1.消费者 决定何时从数据 生产者 中接收数据,生产者本身不知道数据何时会被传递给消费者,函数本身不知道何时会被调用,只有调用函数的人才知道. 2.生产者 决定何时将数据发送给 消费者, 消费者不知道 ...

  2. Subject 与 Observable 的区别

    原文链接:http://javascript.tutorialhorizon.com/2017/03/23/rxjs-subject-vs-observable/ In order to under­ ...

  3. java subject类_RxJava 常见误区(一):过度使用 Subject

    准备写这篇文章的时候看了下 RxJava 在 Github 上已经 12000+ 个 star 了,可见火爆程度,自己使用 RxJava 也已经有一小段时间.最初是在社区对 RxJava 一片赞扬之声 ...

  4. Rxjs Observable

    创建Observable: Rx.Observable.create 是 Observable 构造函数的别名,它接收一个参数:subscribe 函数. 例子:每秒推送一个"Hi" ...

  5. RxJS 核心概念之Subject

    本文出处:https://segmentfault.com/a/1190000005069851,我做了一部分修改 我们在接触到RxJS的时候,不免会有点晕头转向的感觉,对于什么是Subject,什么 ...

  6. redux rxjs_可观察的RxJS和Redux入门指南

    redux rxjs Redux-Observable is an RxJS-based middleware for Redux that allows developers to work wit ...

  7. RxJava 和 RxAndroid 一 (基础)

    1.RxJava 项目地址 https://github.com/ReactiveX/RxJava 2.RxAndroid 项目地址    https://github.com/ReactiveX/R ...

  8. java品酒会,我学 rxjava 2(3)- 热发射

    这篇文章离上一篇文章有些时日了,概因最难心情大大的不好,非常不爽. 为啥我会专门写一下热发射呢,因为 RxBus 就是使用 RxJava 的热发射(Subject)实现的,但是呢我的出发点不同,我是因 ...

  9. java jdk 观察者模式_java观察者模式实现和java观察者模式演化

    简单的观察者模式实现 import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; impo ...

  10. Rxjs 的一些学习笔记

    源自观察者-发布者设计模式: 观察者注册于 Subject 上,每当 subject 状态发生变化时,通知观察者. RxJs 里的 Observable 就是 Subject: 管道:连接 Obser ...

最新文章

  1. 【怎样写代码】工厂三兄弟之工厂方法模式(一):问题案例
  2. 图像滤波常用算法实现及原理解析
  3. 关于主机的思维导图_几张思维导图,让你清楚的知道ip地址怎么回事?
  4. <DependencyManagement>记录
  5. C# ASP.NET MVC HtmlHelper用法大全
  6. 一层循环时间复杂度_数据结构与算法系列——时间、空间复杂度
  7. ELK --- Grok正则过滤Linux系统登录日志
  8. Hibernate的导入和逆向工程生成JavaBean
  9. Memory Cleaner for Mac(内存清理工具)最新版
  10. 60、在Visual Studio 2019 环境下,使用C#调用C++生成的dll实现yolov5的图片检测
  11. Kettle 添加备注
  12. php 漏洞扫描,10个最佳PHP代码安全扫描程序来查找漏洞
  13. XP 操作系统安全防范
  14. FPGA数字系统设计(9)——信号产生
  15. 求阶乘问题c语言编程,求阶乘问题
  16. 用libpcap分析CAIDA的网络流量文件的猝发性
  17. android 选择答题功能,Android实现简单的答题系统
  18. 百度,你是神一样的搜索引擎
  19. java 静态数组_java(四)创建静态数组
  20. 计算机基础教学改革申报书,混合教学试点课程改革项目申报书-《计算机文化基础》...

热门文章

  1. 无法打开internet站点,ie无法打开站点的解决方法【图解】
  2. 移动硬盘计算机无法打开硬盘,移动硬盘无法访问,详细教您移动硬盘无法访问怎么办...
  3. 捷径系统智慧健身房管理系统方案
  4. 图解 Android 事件分发机制
  5. pandas:sample函数解释
  6. ceph RBD块存储常规操作
  7. unity简单的脚本 播放3D立体音效(近大远小效果)
  8. CANoe CAPL文件操作目录合集
  9. RK987蓝牙键盘使用说明书分享
  10. plsql删除历史记录