RxSwift 入坑解讀-你所需要知道的各種概念

發表於2016-12-27

相信大家很早就聽說過函式式響應程式設計概念,我是去年面試的時候接觸到函式式響應程式設計的,當時也是第一次接觸到MVVM這個概念,轉眼都一年過去了,我卻沒有在函數語言程式設計上做深入的研究,說來還真是慚愧。

不過最近由於想要使用RxSwift,所以趁這個時候好好接觸和研究一下傳說中的函數語言程式設計,由於網上關於RxSwift的教程資料很少,這篇文章其實就是最RxSwift官方文件和一些概念做一些解讀。算是大家學習的參考文章吧! 先挖個坑,這可能會是一個RxSwift系列,希望大家在學習的時候有所參考。

這篇文章也釋出在我的部落格中,閱讀效果更棒哦!

RxSwift是什麼

RxSwif是ReactiveX的Swift版本,也就是一個函式式響應程式設計的框架。對,就這一句話。想要知道他做什麼的,我們先來了解一下觀察者模式。

觀察者模式

關於觀察者模式我想大夥應該都很瞭解了吧,什麼KVO,通知等都是觀察者模式,在設計模式中他可是一個重中之重的設計模式啊!比如一個寶寶在睡覺,爸爸媽媽,爺爺奶奶總不能在那邊一隻看著吧?那樣子太累了。他們該做啥事就做啥事唄,只要聽到寶寶的哭聲,他們就給寶寶餵奶就行了。這就是一個典型的觀察者模式。寶寶是被觀察者,爸爸媽媽等是觀察者也稱作訂閱者,只要被觀察者發出了某些事件比如寶寶哭聲、叫聲都是一個事件,通知到訂閱者,訂閱者們就可以做相應的處理工作。哈哈,觀察者模式很簡單吧?

RxSwift做了什麼

RxSwift把我們程式中每一個操作都看成一個事件,比如一個TextField中的文字改變,一個按鈕被點選,或者一個網路請求結束等,每一個事件源就可以看成一個管道,也就是sequence,比如TextField,當我們改變裡面的文字的時候,這個TextField就會不斷的發出事件,從他的這個sequence中不斷的流出,我們只需要監聽這個sequence,每流出一個事件就做相應的處理。同理,Button也是一個sequence,每點選一次就流出一個事件。也就是我們把每一步都想成是一個事件就好去理解RxSwift了。看下圖是不是很好理解了?

11693607-539880f0dd058976

sequence.png

Observable和Observer

理解了觀察者模式這兩個概念就很好理解了,Observable就是可被觀察的,也就是我們說的寶寶,他也是事件源。而Observer就是我們的觀察者,也就是當收到事件的時候去做某些處理的爸爸媽媽。觀察者需要去訂閱(subscribe)被觀察者,才能收到Observable的事件通知訊息。

下面開始一些基本概念解讀,通讀一遍你會對RxSwift有非常深刻的認識了,其實也就是對整理了一下官方文件和加上自己的一些理解

建立和訂閱被觀察者

下面建立被觀察者其實就是建立一個Obserable的sequence,就是建立一個流,然後就可以被訂閱subscribe,這樣被觀察者發出時間消失,我們就能做相應的處理

DisposeBag

DisposeBag其實就相當於iOS中的ARC似得,會在適當的時候銷燬觀察者,相當於記憶體管理者吧。

subscribe

subscribe是訂閱sequence發出的事件,比如next事件,error事件等。而subscribe(onNext:)是監聽sequence發出的next事件中的element進行處理,他會忽略error和completed事件。相對應的還有subscribe(onError:) 和 subscribe(onCompleted:)

never

never就是建立一個sequence,但是不發出任何事件訊號。

12693607-b3487ed03ec04e5c

never.png

empty

empty就是建立一個空的sequence,只能發出一個completed事件

13693607-f57e76a6830fef08

empty.png

just

just是建立一個sequence只能發出一種特定的事件,能正常結束

14693607-e3ee91873f021bcf

just.png

of

of是建立一個sequence能發出很多種事件訊號

如果把上面的onNext:去掉的話,結果會是這樣子,也正好對應了我們subscribe中,subscribe只監聽事件。

from

from就是從集合中建立sequence,例如陣列,字典或者Set

create

我們也可以自定義可觀察的sequence,那就是使用create

15693607-95889cfe73da98ae

create.png

create操作符傳入一個觀察者observer,然後呼叫observer的onNext,onCompleted和onError方法。返回一個可觀察的obserable序列。

range

range就是建立一個sequence,他會發出這個範圍中的從開始到結束的所有事件

16693607-3cc210e164e60e03

range.png

repeatElement

建立一個sequence,發出特定的事件n次

17693607-4533773906429a2f

repeat.png

generate

generate是建立一個可觀察sequence,當初始化的條件為true的時候,他就會發出所對應的事件

deferred

deferred會為每一為訂閱者observer建立一個新的可觀察序列

18693607-291576531e859653

defered.png

下面例子中每次進行subscribe的時候都會去建立一個新的deferredSequence,所以Emitting會列印兩遍。

error

建立一個可觀察序列,但不發出任何正常的事件,只發出error事件並結束

doOn

doOn我感覺就是在直接onNext處理時候,先執行某個方法,doOnNext( :)方法就是在subscribe(onNext:)前呼叫,doOnCompleted(:)就是在subscribe(onCompleted:)前面呼叫的。

學會使用Subjects

Subjet是observable和Observer之間的橋樑,一個Subject既是一個Obserable也是一個Observer,他既可以發出事件,也可以監聽事件。

PublishSubject

當你訂閱PublishSubject的時候,你只能接收到訂閱他之後發生的事件。subject.onNext()發出onNext事件,對應的還有onError()和onCompleted()事件

19693607-2c41f649b52606f5

publishsubject.png

ReplaySubject

當你訂閱ReplaySubject的時候,你可以接收到訂閱他之後的事件,但也可以接受訂閱他之前發出的事件,接受幾個事件取決與bufferSize的大小

20693607-aa9d4953bf6d3a84

replaysubject.png

BehaviorSubject

當你訂閱了BehaviorSubject,你會接受到訂閱之前的最後一個事件。

21693607-5b6fcf5d70780604

behaviorsubject.png

PublishSubject, ReplaySubject和BehaviorSubject是不會自動發出completed事件的。

Variable

Variable是BehaviorSubject一個包裝箱,就像是一個箱子一樣,使用的時候需要呼叫asObservable()拆箱,裡面的value是一個BehaviorSubject,他不會發出error事件,但是會自動發出completed事件。

聯合操作

聯合操作就是把多個Observable流合成單個Observable流

startWith

在發出事件訊息之前,先發出某個特定的事件訊息。比如發出事件2 ,3然後我startWith(1),那麼就會先發出1,然後2 ,3.

22693607-8f60ab3c900aa790

startwith.png

merge

合併兩個Observable流合成單個Observable流,根據時間軸發出對應的事件

23693607-f2f8af4760c09dd1

merge.png

zip

繫結超過最多不超過8個的Observable流,結合在一起處理。注意Zip是一個事件對應另一個流一個事件。

24693607-72fdd28f1d8ca29c

zip.png

combineLatest

繫結超過最多不超過8個的Observable流,結合在一起處理。和Zip不同的是combineLatest是一個流的事件對應另一個流的最新的事件,兩個事件都會是最新的事件,可將下圖與Zip的圖進行對比。

25693607-edecc427c26d4b3a
combinlatest.png

switchLatest

switchLatest可以對事件流進行轉換,本來監聽的subject1,我可以通過更改variable裡面的value更換事件源。變成監聽subject2了

26693607-f3ca896faf6de818

switch.png

變換操作

map

通過傳入一個函式閉包把原來的sequence轉變為一個新的sequence的操作

27693607-0687f1e73b8bd339

transform.png

flatMap

將一個sequence轉換為一個sequences,當你接收一個sequence的事件,你還想接收其他sequence發出的事件的話可以使用flatMap,她會將每一個sequence事件進行處理以後,然後再以一個sequence形式發出事件。而且flatMap有一次拆包動作,請看程式碼解析。

28693607-695c20af1152bca7

flatmap.png

flatMapLatest

flatMapLatest只會接收最新的value事件,將上例改為flatMapLatest。結果為

scan

scan就是給一個初始化的數,然後不斷的拿前一個結果和最新的值進行處理操作。

過濾和約束

filter

filter很好理解,就是過濾掉某些不符合要求的事件

distinctUntilChanged

distinctUntilChanged就是當下一個事件與前一個事件是不同事件的事件才進行處理操作

elementAt

只處理在指定位置的事件

single

找出在sequence只發出一次的事件,如果超過一個就會發出error錯誤

take

只處理前幾個事件訊號,

takeLast

只處理後幾個事件訊號

takeWhile

當條件滿足的時候進行處理

takeUntil

接收事件訊息,直到另一個sequence發出事件訊息的時候。

skip

取消前幾個事件

skipWhile

滿足條件的事件訊息都取消

skipWhileWithIndex

滿足條件的都被取消,傳入的閉包同skipWhile有點區別而已

skipUntil

直到某個sequence發出了事件訊息,才開始接收當前sequence發出的事件訊息

數學操作

toArray

將sequence轉換成一個array,並轉換成單一事件訊號,然後結束

reduce

用一個初始值,對事件資料進行累計操作。reduce接受一個初始值,和一個操作符號

concat

concat會把多個sequence和併為一個sequence,並且當前面一個sequence發出了completed事件,才會開始下一個sequence的事件。

在第一sequence完成之前,第二個sequence發出的事件都會被忽略,但會接收一完成之前的二發出的最後一個事件。不好解釋,看例子說明

連線性操作

Connectable Observable有訂閱時不開始發射事件訊息,而是僅當呼叫它們的connect()方法時。這樣就可以等待所有我們想要的訂閱者都已經訂閱了以後,再開始發出事件訊息,這樣能保證我們想要的所有訂閱者都能接收到事件訊息。其實也就是等大家都就位以後,開始發出訊息。

publish

將一個正常的sequence轉換成一個connectable sequence

replay

將一個正常的sequence轉換成一個connectable sequence,然後和replaySubject相似,能接收到訂閱之前的事件訊息。

multicast

將一個正常的sequence轉換成一個connectable sequence,並且通過特性的subject傳送出去,比如PublishSubject,或者replaySubject,behaviorSubject等。不同的Subject會有不同的結果。

錯誤處理

catchErrorJustReturn

遇到error事件的時候,就return一個值,然後結束

catchError

捕獲error進行處理,可以返回另一個sequence進行訂閱

retry

遇見error事件可以進行重試,比如網路請求失敗,可以進行重新連線

debug

debug

列印所有的訂閱, 事件和disposals

RxSwift.Resources.total

檢視RxSwift所有資源的佔用

啊,文章終於結束,這篇文章比較長,基本上涵蓋了官方文件所有的概念,其中不免有些錯誤與疏漏,希望能在你學習RxSwift的時候能有一些參考價值吧!!!

小夥伴們如果感覺文章對你有所幫助,可以關注博主部落格

小夥伴們也可以關注博主微博,探索博主內心世界

如要轉載請註明出處。

相關文章