Subject的抽象应用场景

你想要发射一些数据,但是你不确定这些数据将会在什么时候被发射出来,也不知道他们的数量。
显然 使用just和from不能帮助你完成这个任务 而你也无法使用create来创建一个可以在某些情况下自旋的Observable(这些创建方法的具体区别以后再讲)
最佳的情况就是你拥有一个对象,它既是一个Observable——这样的话使用者可以链接他们,也是一个Observer——这样的话你就可以发射数据(onNext)和终结事件(onCompleted)了。

①PublisSubject
Subject可以被看做为【热Observable】,就算没有观察者(订阅者)监听它,它也会自动工作。
在RxJava中,这样的Subject叫做PublishSubject,我们可以这样创建它:
Subject<String, String> changeEvents = PublishSubject.create();
显然 使用create工厂方面能够帮助我们避免重复输入泛型参数,但是我们为什么不能再Rx.Net中 使用new PublishSubject<>()呢?理由在于流式API的产生原理。
如果你还记得的话,当你通过create方法创建Observable的时候,你需要提供一个OnSubscriber实例,当一个订阅者订阅这个
Observable的时候,最终会调用OnSubscribe的call方法。
不像【冷Observable】(create方式创建的就是冷的),Subject必须追踪他们的使用者,这种追踪既发生在内部的OnSubscribe中,也发生在Subject自己身上。很不幸,Java并不允许一个在构造函数中的内部类去访问父类的成员,因此,这种共享的变量必须提取到另外一个独立的类里面然后展示给他们。这种重要的机制就隐藏在PublishSubject.create工厂方法里面。(看了下源码,这个类叫做SubjectSubscriptionManager)

②ReplaySubject
有时候你并不想立刻分发时间,而是等待一个合适的时机。
比如说,你是一个电视台网络并且每周播放大量的电视连续剧。但是,你的一些使用者并不总是能够跟得上播放的节奏,但是他们也不想错过某一集。因此,他们的智能电视提供了一种缓存电视连续剧的能力,在某一个节点开始,允许订阅者以它自己的步子观察序列,并且不错过任何一个。

在RxJava里,这样的Subject叫做ReplaySubject。默认情况下,你可以创建一个无边界的ReplaySubject对象,它可以缓存所有它接收到的数据并且重播给他的订阅者,包括那些已经终结的事件。
然而,在一些用例中,你希望限制一个最大事件或者是希望缓存的事件数量,RxJava提供了以下三种额外的重播模式:
①createWithSize(n):最多保留n个元素
②createWithTime(t,u):保留那些比t年轻的元素
③createWithTimeAndSize(n,t,u):最多保留n个元素并且要比t年轻
在大多数情况下,这些就足够用了。

③AsyncSubject
然而,考虑这样一种情形,你进行了一种异步运算并且只想发射完成事件中的那个结果值。
ReplaySubject确实也起作用(从头开始计算一遍)但是这样做的话不仅冗余代价也太高昂了。
因此RxJava提供了另外一种Subject叫做AsyncSubject,它能记住它最后接收到的元素并且一旦onCompleted方法被调用(需要你显示调用它),所有当前的和未来的监听器都将会接受到completion事件的那个单一的值。但是和ReplaySubject不同,一旦一个事件调用了onError方法,那么所有之前接受到的值都将被忽略并且所有的订阅者都将接收到Throwable这个错误提示对象。

④BehaviorSubject
在RxJava中的最后一种情况是你只想保留最后一个事件。一样,ReplaySubject也能够办到(将元素设为1),但是和ReplaySubject不同,你一旦调用onCompleted方法,它会驱逐保存的值,那些在子序列中的订阅者无法接收到这个值而只是会接受到onCompleted(或者onError)事件而已。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容