RxSwift整理

RxSwift

Definition:
Use concept of Observer pattern and sequence operators, let us handle asynchronous data/event together in a declarative manner

The tools(i.e. objects) provided:

  • Observable
  • Operators
  • Subject
  • Scheduler

Observable

Definition:
The object that emits data/event asynchronously

Functions:

  • subscribe/unsubscribe
  • Manage life time

Operators

Definition:
Provide the way to handle data collection after receiving data/event from observable

Functions:

  • Creating Observables
  • Transforming Observables
  • Filtering Observables
  • Combining Observables
  • Error Handling Operators
  • Observable Utility Operators
  • Conditional and Boolean Operators
  • Mathematical and Aggregate Operators
  • Backpressure Operators
  • Connectable Observable Operators

Subject

Definition:
Acts both as an observer and as an Observable. Because it is an observer, it can subscribe to one or more Observables, and because it is an Observable, it can pass through the items it observes by reemitting them, and it can also emit new items.

Scheduler

Definition:
introduce multithreading into your cascade of Observable operators, you can do so by instructing those operators (or particular Observables) to operate on particular Schedulers.

Operators for specifying which thread:

  • SubscribeOn (p.s. specifying a different Scheduler on which the Observable should operate)
  • ObserveOn (p.s. specifies a different Scheduler that the Observable will use to send notifications to its observers.)

RxSwift使用

以下資料參考自Ref,這裡僅作個人學習整理

Rx的一個核心觀念就是observable(或叫sequence ),口訣就是,Everything is a SEQUENCE,大意就是在Rx的世界,都是由observable構成。

Observable的生命週期:

  1. 使用.subscribe來訂閱Observable
  2. 當訂閱者收到Observable發出的.next、.error、.completed事件時,會依據我們定義好的程式執行
  3. Dispose
    Note:
    當我們subscribe()時,就會產生一個Disposable,當今天deinit時,Observable卻還沒結束,這時裝在DisposeBag中的所有Disposable就會執行dispose(),藉此來釋放資源

建立Observable方式:

  • .of
  • .interval
  • .just
  • .from
  • .never (p.s. 不會發送也不會結束的Observable)
  • .empty (p.s. 只會發送.completed的Observable)
  • .error (p.s. 只會發送.error的Observable,在測試的時候比較常用到。)
  • .create (p.s. 提供你客製化Observable方式)

Subject:
他同時是Observable跟Observer
Note:
疑問: 為什麼需要「Subject」? 單純是為了方便簡化code??

Subject種類?:

  • PublishSubject (p.s. 開始是空的,只會發送新的元素給訂閱者)
  • BehaviorSubject (p.s. 它定義是『開始是預設值,發送目前的最後一個值給訂閱者』,也就是說你不管什麼時候訂閱,都會有元素可以收到(至少有預設值)。)
  • ReplaySubject (p.s. 開始時給訂一個暫存大小(buffer size),發送時會將最後的n個元素存進暫存,並將暫存的元素發給訂閱者)
  • AsyncSubject(這很少用到,就不提了)
  • PublishRelay (p.s. 只接受.next事件,不接受.error或.completed. Note: 從source code來看,PublishRelay其實就是PublishSubject再包一層)
  • BehaviorRelay(p.s. 只接受.next事件,不接受.error或.completed. Note: 從source code來看,BehaviorRelay其實就是BehaviorSubject再包一層)

注意事項:
你會發現,Subject在同個class或是不同class被到處被onNext(),Relay被到處.accept(),這樣我們又回到Imperative思維,並且在Imperative上包一層的感覺,反而更不舒服,寫久了會很亂,也會常常出錯。
EX:
Observable
.subscribe(onNext: {
observerA.onNext(…)
observerB.onNext(…)
observerC.onNext(…)
})
.disposed(by: disposeBag)

#

Filtering Observables:
使用範例:
Observable.of(1, 2, 3, 4, 5)
.debug(“A")
.filter { $0 % 2 == 1 }
.debug(“B")
.subscribe()
.disposed(by: disposeBag)

說明:
只有滿足closure內條件的元素才會被執行

Skip Observables:
「skip」使用範例:
Observable.of(1, 2, 3, 4, 5)
.skip(2)
.debug(“B")
.subscribe()
.disposed(by: disposeBag)

說明:
略過前兩個元素(i.e. 1, 2)

「skipWhile」使用範例:
Observable.of(1, 3, 5, 6, 7)
.skipWhile { $0 % 2 == 1 }
.debug(“B")
.subscribe()
.disposed(by: disposeBag)

說明:
略過符合條件的元素,直到遇到不符合條件的元素(即 false),就停止略過
p.s. 範例中的1, 3, 5, 6, 7,只有6和7會執行

「skipUntil」使用範例:
let subject = PublishSubject()
let trigger = PublishSubject()
subject
.skipUntil(trigger)
.debug(“B")
.subscribe()
.disposed(by: disposeBag)
subject.onNext(“1″)
subject.onNext(“2″)
trigger.onNext(())
subject.onNext(“3″)
subject.onNext(“4″)

說明:
定義『略過元素,直到另一個Observable發送元素,就停止略過』,跟前面兩種相比,前面兩種是靜態的設定過濾條件,skipUntil則是可以基於另一個Observable 去動態過濾元素。

Take Observables:
take跟skip就是相反的存在,前者是取的n個元素,後者是略過n個元素,同樣的,它也有takeWhile跟takeUntil。

DistinctUntilChanged:
定義『排除重複的元素,直到不是重複時,才會發出』,比如下方範例,當true轉false時才會發送元素
使用範例:
Observable.of(true, true, false, false, true, false)
.distinctUntilChanged()
.debug(“B")
.subscribe()
.disposed(by: disposeBag)
執行結果:
B -> subscribed
B -> Event next(true)
B -> Event next(false)
B -> Event next(true)
B -> Event next(false)
B -> Event completed
B -> isDisposed

Getting started with RxSwift

以下資料參考自Ref,這裡僅作個人學習整理

  • Definition of ReactiveX
  • Advantage of ReactiveX
  • Definition of RxSwift
  • Example of RxSwift
  • 補充

Definition of ReactiveX:

  • An API for asynchronous programming with observable streams.
  • ReactiveX is a combination of the best ideas from the Observer pattern, the Iterator pattern, and functional programming.
  • ReactiveX是一組tool讓指令式程式設計(imperative programming)的程式語言能夠不用管資料是同步或非同步的狀況下去操作資料序列。它提供了一組sequence operators來操作在序列上的每個item。

用一句話說明Rx:

利用observer pattern和sequence operators,讓我們能夠用宣告式(declarative)的方式去處理同步或非同步的data or event stream。

Advantage of Rx:

  • Composable, Reusable (p.s. 訂閱者模式優點)
  • Understandable and concise (p.s. Declartive優點)
  • 避免Mutable state,讓資料流呈單向流動 (p.s. Function Reactive programming優點)
  • 方便處理非同步事件(p.s. Reactive programming的優點)

Definition of RxSwift

RxSwift is the Swift-specific implementation of the Reactive Extensions standard.

Note:

有人說Rx是Functional Reactive Programing(FRP),在官方介紹中有特別說明,這不是那麼正確,Rx可能會是Functional,可能會是Reactive,但FRP是另外一件東西,在定義的上 FRP 則是隨著時間continuously(連續的)操作數值,Rx則是 discrete(離散的)

Example of RxSwift

每0.5秒輸出一個累進數值,藉由subscribe,觸發到onNext這個closure,印出收到的數值

       let observable = Observable<Int>.interval(.milliseconds(500), scheduler: MainScheduler.instance)
        observable
            .subscribe(onNext: { element in
                print(element)
            }, onError: { error in
                print(error)
            }, onCompleted: {
                print("onCompleted")
            }, onDisposed: {
                print("onDisposed")
            })

補充:

  • Observer pattern(觀察者模式)
  • Iterator pattern(疊代器模式)
  • Imperative programming(指令式程式設計)
  • Declarative programming(宣告式程式設計)
  • Functional programming(函式語言程式設計)

Collections:

  • In Rx, you begin with a collection and end with a collection
  • Rx methods, also called operators, always return a new collection and never mutate the passed collection

Ref: https://www.slideshare.net/rockncoder/a-quick-intro-to-reactivex

待整理部分:

  • Observer pattern研究與分析
  • Iterator pattern研究與分析

Ref:

https://ithelp.ithome.com.tw/articles/10237162

https://www.slideshare.net/rockncoder/a-quick-intro-to-reactivex

https://github.com/ReactiveX/RxSwift