RxSwift 基本入門

RxSwift 初心者入門

在之前我們稍微提過 RxSwift 這一個 framework ,也有稍微介紹了什麼是 Reactive Programming ,那這邊就來詳細談談如何學習以及使用 RxSwfit 吧。

使用 RxSwift 的 Playground

首先我們先至 RxSwift Clone 整個 Project,接著我們這邊使用 Rx.Playground 做為入門的教學,按照官網的操作如下

1
2
3
4
5
6
To use playgrounds:

Open Rx.xcworkspace
Build the RxSwift-macOS scheme
Open Rx playground in the Rx.xcworkspace tree view.
Choose View > Debug Area > Show Debug Area

Imgur

為什麼我們需要使用 RxSwift

我們編寫的大多數程式碼都會設計外部事件的響應。當一個使用者操控一個控制元件,我們需要寫一個 @IBAction 的對應處理。我們需要觀察鍵盤的位置的改變。當 URL sessions 回傳數據時,我們必須提供一個閉包去接受相對應的資料。我們使用 KVO 去檢測變數的變化。所有的這些各式各樣系統的變化使得我們必須去撰寫相對應的代碼,而使得我們的程式碼變的臃腫且複雜,如果有一個一致的系統處理我們所有的呼叫/響應的代碼,這樣我們的程式會不會變得更優雅且美好?Rx是這樣的一個系統,RxSwfit是一個建立在Swift語言上的官方實現版本。

核心概念

Every Observable instance is just a sequence.

每一個 Observable 就只是一個序列而已。

觀察者模式 Observer Pattern 和序列 sequence 本質上是等價的,這在整個 Rx 框架(不僅只限於RxSwift)是很重要的一個基本概念。

Observable 相比 Swift 自帶的 Sequence 優勢在於,RxSwiftObservable 可以非同步的接受元素或者對象,這是整個 RxSwift 的核心。

  • 一個 Observable (ObservableType) 相當於一個 Sequence
  • ObservableType.subscribe(_:) 相等於 Sequence.makeIterator()
  • Observer(callback)需要傳遞給ObservableType.subscribe方法來接受序列裡的元素,代替在返回的 generator 上呼叫 next() 方法。

關於 Observable

在 ReactiveX 中,Observable<Element> 代表的是一個可觀察序列,從字面意思可以看出這是在觀察者模式中的被觀察者,它會向觀察對象發送事件序列:

  • next(Element) : 新事件。
  • error(ErrorType) : 帶有異常的事件完成序列。
  • completed() : 正常事件完結序列。

假如一個 Observable 發射一個 next 事件 ( Event.next(Element) ),那它能夠繼續發射更多的事件,假如 Observable 發射一個 error 事件(Event.error(ErrorType)) 或者一個 completed 事件 (Event.completed),那麼這個 Observable 將再也不能發送事件給訂閱者。

Observable 的序列概念,我們可以很容易地對他做出可視化, 像是下列的序列依樣。

一個簡單的數字序列,| 符號代表正常中斷。

1
--1--2--3--4--5--6--|----> // "|" = Terminates normally

一個字串序列,X 符號代表錯誤中斷

1
--a--b--c--d--e--f--X----> // "X" = Terminates with an error

也有可能是無限的序列,像是一個按鈕的操作序列

1
--tap--tap----------tap--> // "|" = Continues indefinitely, such as a sequence of button taps

上面這些示意圖都被稱為 marble diagram ,這邊有更多的 marble diagram 示意圖 :

RxJS Marbles

一個 Observable 的簡單例子

Observable 除非有訂閱者,否則不會執行他們的 subscription closure

下面的例子, Observableclosure 永遠不會被執行,因為沒有任何訂閱者。( Rx.Playground 中運行的範例)

1
2
3
4
5
6
7
8
example("Observable with no subscribers") {
_ = Observable<String>.create { observerOfString -> Disposable in
print("This will never be printed")
observerOfString.on(.next("😬"))
observerOfString.on(.completed)
return Disposables.create()
}
}

輸出結果 :

1
--- Observable with no subscribers example ---

在下面的例子, closuresubscribe(_:) 被調用時執行。

1
2
3
4
5
6
7
8
9
10
11
example("Observable with subscriber") {
_ = Observable<String>.create { observerOfString in
print("Observable created")
observerOfString.on(.next("😉"))
observerOfString.on(.completed)
return Disposables.create()
}
.subscribe { event in
print(event)
}
}

輸出結果 :

1
2
3
4
--- Observable with subscriber example ---
Observable created
next(😉)
completed

這邊先不關心如何建立這些 Observable 的細節,我們將在後面會提到。