冷熱可觀察量RxJava 學習筆記<二十二>

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肯定要存儲和重放的最大項目數。訂閱後,observable將重放最後一個bufferSize項目數,舊的被遺棄。這對於節省內存頗有用。
  • time, unit肯定元素在被遺棄以前。訂閱後,observable將replay比時間更新的項目。
  • 選擇器將以與發佈(選擇器)相同的方式轉換重放的observable。

這是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

有什麼討論的內容,能夠加我公衆號:

相關文章
相關標籤/搜索