冷热可观察量RxJava 学习笔记

Hot and Cold observables

可观察序列有两种形式,称为“热”和“冷”,具有重要差异。在本章中,我们将解释每种类型的含义以及对于您作为Rx开发人员的意义。

冷可观察量(Cold observables)

冷可观察序列当它们被订阅时,它们运行它们的序列,从一开始就向每个用户呈现序列。冷可观察序列的一个例子是Observable.interval。无论何时创建以及何时订阅,它都将为每个订阅者生成相同的序列。

16b7669bd9bf33aeadc64f2db8aa7993920.jpg

输出:

b7f4c65ee882678e3fca996ea286473de1e.jpg

两个订阅者不会同时收到相同的值,即使他们都订阅了相同的observable。确实看到了相同的序列,除了他们每个人都认为它们在订阅时已经开始。

到目前为止,我们在本指南中看到的代码示例都是冷可观察序列,因为冷可观察量更易于推理。使用Observable.create创建的每个可观察对象都是冷可观察的。这包括我们所见过的所有缩写,例如just,range,timer和from。

冷可观察量不一定对每个用户呈现相同的序列。例如,如果observable连接到数据库并发出查询结果,则实际值将取决于订阅时数据库的状态。事实上,订阅者将从一开始就接收整个查询,这使得这种可观察的冷却。

热可观察量(Hot observables)

热可观察值的发出独立于个人订阅。他们有自己的时间表,无论是否有人在听,都会发生事件。一个例子是鼠标事件。无论是否有订阅,鼠标都会生成事件。订阅完成后,观察者会在事件发生时收到这些事件。您没有收到,并且您不希望收到自启动系统以来鼠标所做的所有事情的回顾。取消订阅时,它也不会阻止鼠标生成事件。你只是没有收到它们。如果您重新订阅,您将再次看到当前事件,而无法回顾您错过的内容。

Publish

有很多方法可以将冷观测值变为热观测值,反之亦然。使用publish()运算符,Cold Observable变得"热"。

f0cf3ab74e3f98179cd8368ea58eaed69f6.jpg

publish返回一个ConnectableObservable <T>,它是Observable <T>的扩展,带有三个附加方法

e7ccc686b0866849e7ecf77a4d86410d9c8.jpg

有一个变量采用选择器在发布序列之前转换序列

cdeb365b6421061dd9a295fedff762c6eb2.jpg

selector可以执行我们在observable上学到的任何操作。这样做的用处是为选择器进行单个订阅,可以根据需要重复使用。如果没有这个重载,重用observable可能会导致多个订阅。

此方法返回Observable <T>而不是ConnectableObservable <T>,因此我们即将讨论的连接功能不适用于此。

connect

ConnectableObservable最初不会发出任何内容。当调用connect时,它将为其source observable(我们称之为发布的那个)创建一个新的订阅。它将开始接收事件并将其推送给其订阅者。所有订阅者将同时收到相同的事件,因为他们实际上共享相同的订阅。

96debd28049616011e0511275a3e432bc62.jpg

输出:

4288754a0906c22b4317bd5300a6a27db9d.jpg

Disconnecting

我们在connect的定义中看到,这个方法返回一个Subscription,就像Observable.subscribe一样。您可以使用该引用来终止ConnectableObservable的订阅。这将阻止事件传播给观察者,但它不会取消订阅ConnectableObservable。如果再次调用connect,ConnectableObservable将启动新订阅,旧观察者将再次开始接收值。

91ccfff920f8c9ce416923757d85d76bc56.jpg

输出:

a674c8daa873e61af8d631b939f2c90d806.jpg

通过再次调用connect重新启动时,将创建一个新订阅。如果source observable是冷的,那意味着整个序列重新启动。

如果您不想终止连接,而是想取消订阅hot observable,则可以使用subscribe方法返回的订阅。

33b4cc746e176e079eb93458d77ae59c0fa.jpg

输出:

1a9c1dfadbfa1289b7e66ed22b02351fc09.jpg

refCount

只要有订阅者,ConnectableObservable.refCount就会返回已连接的Observable <T>。

b6082236d43f1bb16a8972de43f59f3d005.jpg

输出:

1b66ef19cb2f933f2576987dfd5576828cd.jpg

我们在这里看到,在有refCount订阅者之前,序列才会开始。如果它们全部消失,则连接停止。如果以后有更多,则会启动新连接。

replay

c233fb23a322809a58657b67f60783bcdee.jpg

replay类似于ReplaySubject。连接后,它将开始收集值。一旦新的观察者订阅了observable,它就会将所有收集的值重放到它上面。一旦它赶上,它将与其他观察者并行接收值。

d8198b7e0ef75d65f37eaf0ba76a7175fd2.jpg

输出:

ee5c9a37ed35d1d46218cbe1ec65b71b12f.jpg

replay返回一个类似于publish的ConnectableObservable,因此我们可以使用相同的方法取消订阅或创建一个refCount observable。

replay有8个重载

50457a1e7c67320e64669f170cb89ee1d96.jpg

它们是提供3个参数中的一个或多个的不同方式:bufferSize,selector和time(加上时间单位)。

  • bufferSize确定要存储和重放的最大项目数。订阅后,observable将重放最后一个bufferSize项目数,旧的被遗弃。这对于节省内存很有用。
  • time, unit确定元素在被遗弃之前。订阅后,observable将replay比时间更新的项目。
  • 选择器将以与发布(选择器)相同的方式转换重放的observable。

这是bufferSize的一个例子:

507e1f58c34935865d633f27ab34f69c178.jpg

输出:

eee47b4d03cf1c4ec9fe066b75bf5694220.jpg

当我们连接时,源开始以1s间隔发射序列0,1,2,3,4。我们在订阅之前睡了4.5秒,这意味着源已经发出0,1,2,3。0和1从缓冲区中掉落,因此只重放2和3。当发射4时,我们正常接收它。

提供时间窗口时,值会根据时间从缓冲区中消失。

03555a992fd5dba1bcbf9a2328b67db4ad9.jpg

输出:

14e33991c662a5e634b9260ff6cd7c64b88.jpg

cache

cache操作符具有类似的重放功能,但隐藏了ConnectableObservable并删除了订阅的管理。第一个观察者到达时,内部ConnectableObservable被订阅。后续订阅者具有从缓存中重放的先前值,并且不会导致对源可观察对象的新订阅。

321b7d5dffdc6334e72c21bf10c343f2a29.jpg

72129f63db8bb06bcbd012510149a61af19.jpg

输出:

778c8f506b14b50d494e91123fba815b3a8.jpg

在这个例子中,我们看到序列不是在创建observable时开始,而是在第一个用户在500ms之后到达时开始。第二个订阅者在订阅时赶上了早期的值,并且通常会收到未来的值。

需要注意的一点是,如果所有订阅都消失了,内部的ConnectableObservable不会取消订阅,就像refCount那样。一旦第一个订阅到达,将一次性返回观察和缓存源。这很重要,因为我们不能再远离无限的可观察者了。值将继续缓存,直到源终止或内存不足。指定容量的重载也不是解决方案,因为容量是作为优化提示接收的,并且实际上不会限制缓存的大小。

3a7139a0760e4468777bf4331cd5f100d5f.jpg

输出:

e1385d3934b43d3720d599982d4faa0993c.jpg

在此示例中,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

有什么讨论的内容,可以加我公众号:

转载于:https://my.oschina.net/sfshine/blog/3026376

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值