徹底搞懂 RxJava — 中級篇
前言
本文獻給所有想要深入瞭解 RxJava 的人.
如果你還沒閱讀過基礎部分, 請先補習一下功課. 此外, 強烈建議你先過兩遍原始碼的主要邏輯後再讀本文.
本文帶你理解 RxJava 的實現思路, 並解釋原始碼中如何通過多級 Observable < – > Subscriber 實現 `Observable.map` 等 ‘變換’ 操作.
按照慣例, 還是先看一下用法
這裡比較神奇的地方是這個 `map`. 下面讓我們一步一步的解析 `create` -> `map` -> `subscribe` 所發生的故事.
第一步: 回憶程式碼 `OBSERVABLE.CREATE`
create 後, 我們便有了一個 Observable 物件, 該物件中, 還有 onSubscribe 子物件. 如下圖
第二步: `MAP` 的實現 (難度: 四星半. 等級: 重要)
這個 `map` 實際上做了兩件大事:
1)第一件事兒是 new 了一個 ‘變形函式’, 儲存在了 `OperatorMap.transform` 中
2) new了一個新的 Observable. 這個 Observable 的建構函式中, 傳入了一個新的 OnSubscribe. 整個 `lift` 函式的難點就在於這個 OnSubscribe 物件中. 我們仔細看一下它做了什麼. 它其實也做了兩件大事兒:
a) OnSubscribe.call 函式中, 看一下原始碼:
`hook.onLift(operator).call(o)` 建立了一個新的 Subscriber (實際上是一個 proxy), 並在 `Subscriber.onNext` 中呼叫 `transform` 函式對引數 `t` 進行變形, 然後將變形結果轉發給 `o.onNext`. 這麼上面這些變數都是哪裡的呢? 下面的文字請先記住:
`transform` 實際上就是我們 1) 中分析的那個 ‘變形函式’.
`o` 則是我們還沒分析的 ‘第三步’ 中, `subscribe(…)` 的使用者最終的 Subscriber 物件.
b) OnSubscribe.call 做的第二件事兒是呼叫 ‘第一步’ 中 `create` 建立出來的 Observable.onSubscribe 函式! 注意, 這裡呼叫的不是 `map` 自身建立的 observable, 而是 ‘第一步’ 建立的那個. 看下面這個圖幫助你理解:
很簡單, 該 ‘變形函式’ 儲存在了 `OperatorMap.transform` 中.
總結一下 `map` 的行為:
- 建立了一個新的 Observable,
- 建立了一個新的 OnSubscribe: 其中的 `call` 方法是整個呼叫鏈的關鍵. 它呼叫了上一級 `Observable.onSubscribe.call`, 同時, 還將結果通過 `transform` 對 ‘第一步’ 處理後的結果進行變形, 然後將變形後的結果再轉發給 ‘第三步’ 中 `subscribe(Subscriber…)` 中的 `Subscriber` 處理. 那我們馬上看一下 ‘第三步’.
第三步: `SUBSCRIBE` 觸發整個回撥流程. 我們來看一下主要流程(圖中省略與本步驟無關的其它流程)
這一步也很簡單, 就是通過 `Observable.subscribe` 呼叫該物件的 `Observable.onSubscribe.call` 方法, 然後經過一系列呼叫, 最終由該物件內部臨時建立的 Subscriber 物件(上文中的 proxy 物件) 呼叫使用者目標 Subscriber (即程式碼中 `.subscribe(…)` 中的引數) 的方法.
整體梳理
第一步
第二步
第三步
另:
本人 ps 水平有限, 圖有些凌亂請見諒
科學無國界, 感謝 bruce 和 扔物線大神的優秀文章和從你們那裡盜來的圖
Refs:
Grokking 帶你入門
Grokking RxJava, Part 1: The Basics
Grokking RxJava, Part 2: Operator, Operator
Grokking RxJava, Part 3: Reactive with Benefits
Grokking RxJava, Part 4: Reactive Android
Bruce 大頭鬼
RxJava基本流程和lift原始碼分析
讀原始碼!
ReactiveX/RxJava
walfud 徹底搞懂 RxJava 系列
徹底搞懂 RxJava — 初級篇
徹底搞懂 RxJava — 中級篇
徹底搞懂 RxJava — 高階篇
學以致用:
FlowImageLoader — 基於 RxJava 實現的圖片非同步載入庫. 該庫作者即 ‘徹底搞懂 RxJava 系列` 作者
Rx 規範
ReactiveX — An API for asynchronous programming (其中最有用的是 Contract)
其它
Awesome-RxJava
RxJava Essential CN (幫助你瞭解各種 Operator 的使用)
相關文章
- 徹底搞懂徹底搞懂事件驅動模型 - Reactor事件模型React
- 徹底搞懂 Kubernetes 中的 Events
- 徹底搞懂Python中的類Python
- 徹底搞懂JavaScript中的繼承JavaScript繼承
- 徹底搞懂https原理HTTP
- 徹底搞懂 MySQL 事務的隔離級別MySql
- 徹底搞懂Bean載入Bean
- 徹底搞懂JavaScript作用域JavaScript
- 徹底搞懂 Git-RebaseGit
- 從原理到實戰,徹底搞懂Nginx(高階篇)Nginx
- 徹底搞懂Python 中的 import 與 from importPythonImport
- 執行緒安全(中)--徹底搞懂synchronized(從偏向鎖到重量級鎖)執行緒synchronized
- 一篇文章帶你徹底搞懂join的用法
- 深入JavaScript系列(四):徹底搞懂thisJavaScript
- 一文徹底搞懂BERT
- 徹底搞懂 Channel 實現原理
- 徹底搞懂IO多路複用
- 徹底搞懂HTTPS的加密機制HTTP加密
- 徹底搞懂JavaScript原型和原型鏈JavaScript原型
- 看完讓你徹底搞懂Websocket原理Web
- 混合移動App乾貨:一篇就可以徹底搞懂!APP
- 徹底搞懂Scrapy的中介軟體(二)
- 徹底搞懂Scrapy的中介軟體(一)
- 徹底搞懂Object和Function的關係ObjectFunction
- 從原理到實戰,徹底搞懂NginxNginx
- Flutter(五)之徹底搞懂Dart非同步FlutterDart非同步
- 徹底搞懂原型、原型鏈和繼承原型繼承
- 徹底搞懂瀏覽器Event-loop瀏覽器OOP
- 徹底搞懂Scrapy的中介軟體(三)
- 徹底搞懂 python 中文亂碼問題Python
- 兩萬字長文,徹底搞懂Kafka!Kafka
- 徹底搞懂Composer自動載入原理
- 這一次,徹底搞懂 Go CondGo
- 一文徹底搞懂ZAB演算法,看這篇就夠了!!!演算法
- 一文徹底搞懂Raft演算法,看這篇就夠了!!!Raft演算法
- 執行緒安全(上)--徹底搞懂synchronized(從偏向鎖到重量級鎖執行緒synchronized
- 來吧,一文徹底搞懂Java中的Comparable和ComparatorJava
- 兩張圖徹底搞懂MyBatis的Mapper原理!MyBatisAPP
- 徹底搞懂容器技術的基石: namespace (下)namespace