Subject

Subject可以看成是一个桥梁或者代理,在某些ReactiveX实现中(如RxJava),它同时充当了Observer和Observable的角色。因为它是一个Observer,它可以订阅一个或多个Observable;又因为它是一个Observable,它可以转发它收到(Observe)的数据,也可以发射新的数据。

由于一个Subject订阅一个Observable,它可以触发这个Observable开始发射数据(如果那个Observable是"冷"的--就是说,它等待有订阅才开始发射数据)。因此有这样的效果,Subject可以把原来那个"冷"的Observable变成"热"的。

Subject的种类

针对不同的场景一共有四种类型的Subject。他们并不是在所有的实现中全部都存在,而且一些实现使用其它的命名约定(例如,在RxScala中Subject被称作PublishSubject)。

AsyncSubject

一个AsyncSubject只在原始Observable完成后,发射来自原始Observable的最后一个值。(如果原始Observable没有发射任何值,AsyncObject也不发射任何值)它会把这最后一个值发射给任何后续的观察者。 

然而,如果原始的Observable因为发生了错误而终止,AsyncSubject将不会发射任何数据,只是简单的向前传递这个错误通知。 

BehaviorSubject

当观察者订阅BehaviorSubject时,它开始发射原始Observable最近发射的数据(如果此时还没有收到任何数据,它会发射一个默认值),然后继续发射其它任何来自原始Observable的数据。 

然而,如果原始的Observable因为发生了一个错误而终止,BehaviorSubject将不会发射任何数据,只是简单的向前传递这个错误通知。 

PublishSubject

PublishSubject只会把在订阅发生的时间点之后来自原始Observable的数据发射给观察者。需要注意的是,PublishSubject可能会一创建完成就立刻开始发射数据(除非你可以阻止它发生),因此这里有一个风险:在Subject被创建后到有观察者订阅它之前这个时间段内,一个或多个数据可能会丢失。如果要确保来自原始Observable的所有数据都被分发,你需要这样做:或者使用Create创建那个Observable以便手动给它引入"冷"Observable的行为(当所有观察者都已经订阅时才开始发射数据),或者改用ReplaySubject。 

如果原始的Observable因为发生了一个错误而终止,PublishSubject将不会发射任何数据,只是简单的向前传递这个错误通知。

ReplaySubject

ReplaySubject会发射所有来自原始Observable的数据给观察者,无论它们是何时订阅的。也有其它版本的ReplaySubject,在重放缓存增长到一定大小的时候或过了一段时间后会丢弃旧的数据(原始Observable发射的)。

如果你把ReplaySubject当作一个观察者使用,注意不要从多个线程中调用它的onNext方法(包括其它的on系列方法),这可能导致同时(非顺序)调用,这会违反Observable协议,给Subject的结果增加了不确定性。

RxJava的对应类

假设你有一个Subject,你想把它传递给其它的代理或者暴露它的Subscriber接口,你可以调用它的asObservable方法,这个方法返回一个Observable。具体使用方法可以参考Javadoc文档。

串行化

如果你把 Subject 当作一个 Subscriber 使用,注意不要从多个线程中调用它的onNext方法(包括其它的on系列方法),这可能导致同时(非顺序)调用,这会违反Observable协议,给Subject的结果增加了不确定性。

要避免此类问题,你可以将 Subject 转换为一个 SerializedSubject ,类似于这样:

mySafeSubject = new SerializedSubject( myUnsafeSubject );

4.Subject - Observable和Observer的复合体,也是二者的桥梁相关推荐

  1. 你会用RxJS吗?【初识 RxJS中的Observable和Observer】

    概念 RxJS是一个库,可以使用可观察队列来编写异步和基于事件的程序的库. RxJS 中管理和解决异步事件的几个关键点: Observable: 表示未来值或事件的可调用集合的概念. Observer ...

  2. 设计模式之观察者模式(Observable与Observer)

    1.什么是观察者模式 简单情形:有A.B.C.D等四个独立的对象,其中B.C.D这三个对象想在A对象发生改变的第一时间知道这种改变,以便做出相应的响应或者对策. 上面的这种情形,就是观察者模式. 当然 ...

  3. java observer update_Java_观察者模式(Observable和Observer)

    java.util.Observable中有两个方法对Observer特别重要 ①setChanged()方法 /** * Sets the changed flag for this {@code  ...

  4. RxJava2:Observable和Observer如何传递

    以Observable为例,先上代码: //① ObservableJust<String> observable = (ObservableJust<String>) Obs ...

  5. Observable与Observer

    在Java中通过Observable类和Observer接口实现了观察者模式.一个Observer对象监视着一个Observable对象的变化,当Observable对象发生变化时,Observer得 ...

  6. java observer update_Java_观察者模式(Observable和Observer) -转

    一.观察者模式介绍 在Java中通过Observable类和Observer接口实现了观察者模式.一个Observer对象监视着一个Observable对象的变化,当Observable对象发生变化时 ...

  7. ReactiveX文档中文翻译

    ReactiveX/RxJava文档中文版 项目地址:https://github.com/mcxiaoke/RxDocs,欢迎Star和帮忙改进. 有任何意见或建议,到这里提出 Create New ...

  8. [译] Subject 和 Observable + Observer 的混淆指北[ Android RxJava2 ] ( 这什么鬼系列 ) 第八话...

    原文地址:Confusion between Subject and Observable + Observer [ Android RxJava2 ] ( What the hell is this ...

  9. RXJS 中 Observable 和 Subject

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

最新文章

  1. php表单ajax,PHP表单到Ajax类型
  2. 【算法竞赛学习】资金流入流出预测-挑战Baseline_特征工程
  3. Python中lambda表达式的常见用法
  4. 中台之上(五):业务架构和中台的难点,都是需要反复锤炼出标准模型
  5. 【GDB调试学习笔记】 Makefie上
  6. linux oracle 分号引起大错误
  7. 汽车4S店经营状况分析
  8. Python常用数据库封装方法
  9. Linux 进程与信号的概念和操作 linux process and signals
  10. 系统、驱动相关软件下载
  11. c语言 节日,农历阳历之间转换和节气节日查询C语言编程
  12. 我的世界神秘时代研究笔记计算机,我的世界神秘时代5教程全研究笔记连线一览...
  13. 上海数据交易中心交易系统开放
  14. Android中集成讯飞语音,语音转文字以及文字转语音操作
  15. 用python写注册登录界面web_用Python实现web端用户登录和注册功能
  16. 重置计算机网络设置路由器,路由器登录不上怎么办 如何重新设置路由器
  17. ByteBuf 读取字节数组数据
  18. 稀疏表示人脸识别入门文章-《Robust Face Recognition via Sparse Representation》马毅
  19. 【前言】 VVC理论知识之基本框架
  20. HDU 5387 乱搞

热门文章

  1. conda安装时出现无法定位程序输入点于动态链接库
  2. Kubernetes、k8s从入门到实战
  3. crm首页功能和用户登录
  4. Spring中@component的使用
  5. C++与Java比较(转)
  6. layui 如何动态加载局部页面_python爬虫入门实战(四)!爬取动态加载的页面!
  7. MFC中的SetCapture、ReleaseCapture、GetCapture函数
  8. 用于检测浏览器以及系统环境的js
  9. 教你用笔记本破解无线路由器密码
  10. 【理解RESTful架构】——阮一峰版