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 );

RxJava Subject的更多相关文章

  1. ReactiveX--响应式编程の相关概念 浅析

    在许多软件编程任务中,你或多或少期待你的指令将会按照你已经写好的顺序,依次增量执行和完成.但在ReactiveX,很多指令可以通过“观察者”并行执行,其结果将以任意顺序被捕获.你定义了一种“可观察的形 ...

  2. RXJAVA之Subject

    RxJava中常见的Subject有4种,分别是 AsyncSubject. BehaviorSubject.PublishSubject. ReplaySubject. AsyncSubject 使 ...

  3. Android消息传递之基于RxJava实现一个EventBus - RxBus

    前言: 上篇文章学习了Android事件总线管理开源框架EventBus,EventBus的出现大大降低了开发成本以及开发难度,今天我们就利用目前大红大紫的RxJava来实现一下类似EventBus事 ...

  4. Rxjava Subjects

    上次提到调用observable的publish和connect方法后可以将一个Observable发出的对象实时传递到订阅在上的subscriber. 这个和Rxjava中Subject的概念十分相 ...

  5. RxJava简单的介绍

    1. RxJava简介 Rx(ReactiveX,响应式编程)是一种事件驱动的基于异步数据流的编程模式,整个数据流就像一条河流,它可以被观测(监听),过滤,操控或者与其他数据流合并为一条新的数据流.而 ...

  6. [RxJava^Android]项目经验分享 --- RxLifecycle功能实现分析(一)

      最近在研究RxJava自定义操作符的实现原理,发现成型的项目案例较少.突然想起在项目中应用的RxLifecycle是使用自定义操作符,便拿来研究了一下.分析之前,跟大家了解一些相关操作符和RxLi ...

  7. [Android]基于RxJava、RxAndroid的EventBus实现

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4578699.html  Github:https://gith ...

  8. RxJava 和 RxAndroid 一 (基础)

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

  9. Android--Retrofit+RxJava的简单封装(三)

    1,继续接着上一篇的讲讲,话说如果像上一篇这样的话,那么我们每一次请求一个结构都要创建一堆的Retrofit对象,而且代码都是相同的,我们可以试试封装一下 先创建一个HttpMethods类,将Ret ...

随机推荐

  1. Linux命令之dig命令实例讲解

    1.查看域名的A记录 # dig yahoo.com; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.10.rc1.el6_3.2 <<> ...

  2. EasyUi–8.datebox赋值的问题

    这个问题要从EasyUI的datebox组件说起,小菜用这个组件的时候,发现用$("#id").val()这种形式,居然拿不到文本框的值! 经过度娘的帮助,发现可以用$(" ...

  3. pyqt5最简单操作数据库

    要先安一个包才能使用QtSql通过新立得安装 import PyQt5.QtSql as sql db=sql.QSqlDatabase.addDatabase('QMYSQL') db.setDat ...

  4. SASS详解之混合(mixins)

    SASS详解之混合(mixins)可以出现在SASS的任何地方.有很多类名具有相同或者相似的样式,就可以用SASS中的混合(mixins)来进行编写,然后针对不同类名的不同样式逐一编写. 定义一个混合 ...

  5. Redis Cluster集群的搭建与实践

    Redis Cluster集群 一.redis-cluster设计 Redis集群搭建的方式有多种,例如使用zookeeper等,但从redis 3.0之后版本支持redis-cluster集群,Re ...

  6. mybatis基础之二

    UserMapper.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper ...

  7. Git 无法拉取,Unlink of file '.git/objects/pack/pack-***.pack' failed. Should I try again? (y/n)

    现象 Git 无法拉取,提示: Unlink of file '.git/objects/pack/pack-***.pack' failed. Should I try again? (y/n) 原 ...

  8. RxSwift 系列(六)

    前言 本篇文章将要学习RxSwift中数学和集合操作符,在RxSwift中包括了: toArray reduce concat toArray 将一个Observable序列转化为一个数组,并转换为一 ...

  9. Hibernate 使用MyEclipse简化开发

    在平时开发中写配置文件比较繁琐,在这里写一下如何使用myEclipse简化开发. 1.打开MyEclipse,创建数据库连接 单机测试连接按钮,如果出现成功建立连接,则连接成功. 然后Finish 2 ...

  10. UI/GUI/UE/UX/ID/UED/UCD的区别

    简述: UI (User Interface):用户界面 UE (User Experience):用户体验 ID (Interaction design):交互设计 UID (User Interf ...