Hot and Cold observablesios
可观察序列有两种形式,称为“热”和“冷”,具备重要差别。在本章中,咱们将解释每种类型的含义以及对于您做为Rx开发人员的意义。git
冷可观察量(Cold observables)github
冷可观察序列当它们被订阅时,它们运行它们的序列,从一开始就向每一个用户呈现序列。冷可观察序列的一个例子是Observable.interval。不管什么时候建立以及什么时候订阅,它都将为每一个订阅者生成相同的序列。数据库
输出:缓存
两个订阅者不会同时收到相同的值,即便他们都订阅了相同的observable。确实看到了相同的序列,除了他们每一个人都认为它们在订阅时已经开始。并发
到目前为止,咱们在本指南中看到的代码示例都是冷可观察序列,由于冷可观察量更易于推理。使用Observable.create建立的每一个可观察对象都是冷可观察的。这包括咱们所见过的全部缩写,例如just,range,timer和from。优化
冷可观察量不必定对每一个用户呈现相同的序列。例如,若是observable链接到数据库并发出查询结果,则实际值将取决于订阅时数据库的状态。事实上,订阅者将从一开始就接收整个查询,这使得这种可观察的冷却。3d
热可观察量(Hot observables)对象
热可观察值的发出独立于我的订阅。他们有本身的时间表,不管是否有人在听,都会发生事件。一个例子是鼠标事件。不管是否有订阅,鼠标都会生成事件。订阅完成后,观察者会在事件发生时收到这些事件。您没有收到,而且您不但愿收到自启动系统以来鼠标所作的全部事情的回顾。取消订阅时,它也不会阻止鼠标生成事件。你只是没有收到它们。若是您从新订阅,您将再次看到当前事件,而没法回顾您错过的内容。blog
Publish
有不少方法能够将冷观测值变为热观测值,反之亦然。使用publish()运算符,Cold Observable变得"热"。
publish返回一个ConnectableObservable <T>,它是Observable <T>的扩展,带有三个附加方法
有一个变量采用选择器在发布序列以前转换序列
selector能够执行咱们在observable上学到的任何操做。这样作的用处是为选择器进行单个订阅,能够根据须要重复使用。若是没有这个重载,重用observable可能会致使多个订阅。
此方法返回Observable <T>而不是ConnectableObservable <T>,所以咱们即将讨论的链接功能不适用于此。
connect
ConnectableObservable最初不会发出任何内容。当调用connect时,它将为其source observable(咱们称之为发布的那个)建立一个新的订阅。它将开始接收事件并将其推送给其订阅者。全部订阅者将同时收到相同的事件,由于他们实际上共享相同的订阅。
输出:
Disconnecting
咱们在connect的定义中看到,这个方法返回一个Subscription,就像Observable.subscribe同样。您可使用该引用来终止ConnectableObservable的订阅。这将阻止事件传播给观察者,但它不会取消订阅ConnectableObservable。若是再次调用connect,ConnectableObservable将启动新订阅,旧观察者将再次开始接收值。
输出:
经过再次调用connect从新启动时,将建立一个新订阅。若是source observable是冷的,那意味着整个序列从新启动。
若是您不想终止链接,而是想取消订阅hot observable,则可使用subscribe方法返回的订阅。
输出:
refCount
只要有订阅者,ConnectableObservable.refCount就会返回已链接的Observable <T>。
输出:
咱们在这里看到,在有refCount订阅者以前,序列才会开始。若是它们所有消失,则链接中止。若是之后有更多,则会启动新链接。
replay
replay相似于ReplaySubject。链接后,它将开始收集值。一旦新的观察者订阅了observable,它就会将全部收集的值重放到它上面。一旦它遇上,它将与其余观察者并行接收值。
输出:
replay返回一个相似于publish的ConnectableObservable,所以咱们可使用相同的方法取消订阅或建立一个refCount observable。
replay有8个重载
它们是提供3个参数中的一个或多个的不一样方式:bufferSize,selector和time(加上时间单位)。
这是bufferSize的一个例子:
输出:
当咱们链接时,源开始以1s间隔发射序列0,1,2,3,4。咱们在订阅以前睡了4.5秒,这意味着源已经发出0,1,2,3。0和1从缓冲区中掉落,所以只重放2和3。当发射4时,咱们正常接收它。
提供时间窗口时,值会根据时间从缓冲区中消失。
输出:
cache
cache操做符具备相似的重放功能,但隐藏了ConnectableObservable并删除了订阅的管理。第一个观察者到达时,内部ConnectableObservable被订阅。后续订阅者具备从缓存中重放的先前值,而且不会致使对源可观察对象的新订阅。
输出:
在这个例子中,咱们看到序列不是在建立observable时开始,而是在第一个用户在500ms以后到达时开始。第二个订阅者在订阅时遇上了早期的值,而且一般会收到将来的值。
须要注意的一点是,若是全部订阅都消失了,内部的ConnectableObservable不会取消订阅,就像refCount那样。一旦第一个订阅到达,将一次性返回观察和缓存源。这很重要,由于咱们不能再远离无限的可观察者了。值将继续缓存,直到源终止或内存不足。指定容量的重载也不是解决方案,由于容量是做为优化提示接收的,而且实际上不会限制缓存的大小。
输出:
在此示例中,doOnNext在生成和从源可观察文件缓存时打印值,而doOnSubscribe和doOnUnsubscribe在缓存后显示订阅者。咱们看到值的排放从第一次订阅开始,但忽略了咱们取消订阅的事实。
Multicast
share方法是Observable.publish().refCount()的别名。它容许您的订阅者共享订阅,只要有订阅者,订阅就会保留。
下节再续!
原文:https://github.com/Froussios/Intro-To-RxJava/blob/master/Part%203%20-%20Taming%20the%20sequence/6.%20Hot%20and%20Cold%20observables.md
有什么讨论的内容,能够加我公众号: