1. 程式人生 > >Observable 可觀察序列

Observable 可觀察序列

Observable - 可被監聽的序列

Observable 用於描述元素非同步產生的序列

page45image3835360.png

Observable 這個類是 Rx 框架的核心,我們可以稱它為可觀察序列。
Rx 響應的是流(Stream),在 RxSwift 中,我們稱之為 序列(sequence), 事實上,在這裡 序列 是同一樣東西。

Observable 的作用就是可以非同步地產生一系列的 Event(事件),即一個 Observable<T> 物件會隨著時間推移不定期地發出 event(element : T) 這樣一個東西。
而且這些 Event 還可以攜帶資料,它的泛型 <T>

就是用來指定這個 Event 攜帶的資料的型別。

有了可觀察序列,我們還需要有一個 Observer(訂閱者)來訂閱它,這樣這個訂閱者才能收到 Observable<T> 不時發出的 Event

Observable 的生命週期

  • 1、當序列發出 完成事件(Completed Event) 時,序列終止,不在發出資料
  • 2、當序列發出 錯誤事件(Error Event) 時,序列終止,不在發出資料

Event 事件

檢視 RxSwift 原始碼可以發現,事件 Event 的定義如下:

public enum Event<Element> {
    ///
Next element is produced.
case next(Element) /// Sequence terminated with an error. case error(Swift.Error) /// Sequence completed successfully. case completed }

可以看到 Event 就是一個列舉,也就是說一個 Observable 是可以發出 3 種不同型別的 Event 事件:

  • next:就是那個可以攜帶資料 <T> 的事件,可以說它就是一個“最正常”的事件;

page45image3831328.png

  • error: 表示一個錯誤,它可以攜帶具體的錯誤內容,一旦 Observable 發出了 error event,則這個 Observable 就等於終止了,以後它再也不會發出 event 事件了;

page46image1822208.png

  • completed: 表示 Observable 發出的事件正常地結束了,跟 error 一樣,一旦 Observable 發出了 completed event,則這個 Observable 就等於終止了,以後它再也不會發出 event 事件了。

page46image1820864.png

Observable訂閱、事件監聽、訂閱銷燬

一、訂閱 Observable

使用 subscribe() 方法來訂閱它,接收它發出的 Event

方法一:subscribe with event

// 建立序列(後續講解序列的建立)
let observable = Observable.of("A", "B", "C")
// 序列的訂閱
observable.subscribe { event in
    print(event)
}

方法二:subscribe with onNext

方法的 onNext、onError、onCompleted 和 onDisposed 這四個回撥 block 引數都是有預設值的,即它們都是可選的

// 建立序列(後續講解序列的建立)
let observable = Observable.of("A", "B", "C")
// 序列的訂閱
observable.subscribe(onNext: { element in
    print(element)
}, onError: { error in
    print(error)
}, onCompleted: {
    print("completed")
}, onDisposed: {
    print("disposed")
})

二、監聽事件的生命週期

  • 使用 doOn 方法來監聽事件的生命週期,它會在每一次事件傳送前被呼叫
  • 通過不同的 block 回撥處理不同型別的 event

比如:

  • do(onNext:) 方法就是在 subscribe(onNext:) 前呼叫

  • 而 do(onCompleted:) 方法則會在 subscribe(onCompleted:) 前面呼叫

程式碼示例:

let observable = Observable.of("A", "B", "C")

observable
    .do(onNext: { element in
        print("Intercepted Next:", element)
    }, onError: { error in
        print("Intercepted Error:", error)
    }, onCompleted: {
        print("Intercepted Completed")
    }, onDispose: {
        print("Intercepted Disposed")
    })
    .subscribe(onNext: { element in
        print(element)
    }, onError: { error in
        print(error)
    }, onCompleted: {
        print("completed")
    }, onDisposed: {
        print("disposed")
    })

三、Observable 的銷燬(Dispose)

Observable 從建立到終結流程
- 一個 Observable 序列被創建出來後它不會馬上就開始被啟用從而發出 Event,而是要等到它被某個人訂閱了才會啟用它
- 而 Observable 序列啟用之後要一直等到它發出了 .error 或者 .completedevent 後,它才被終結

方法 1:dispose() 方法
- 使用該方法我們可以手動取消一個訂閱行為
- 如果我們覺得這個訂閱結束了不再需要了,就可以呼叫 dispose() 方法把這個訂閱給銷燬掉,防止記憶體洩漏
- 當一個訂閱行為被 dispose 了,那麼之後 observable 如果再發出 event,這個已經 dispose 的訂閱就收不到訊息了

下面是一個簡單的使用樣例:

let observable = Observable.of("A", "B", "C")

// 使用subscription常量儲存這個訂閱方法
let subscription = observable.subscribe { event in
    print(event)
}

// 呼叫這個訂閱的dispose()方法銷燬當前序列
subscription.dispose()

方法 2:DisposeBag

  • DisposeBag 物件可以看成一個記憶體存放包,把用過的訂閱行為都放進去
  • 而這個 DisposeBag 就會在自己快要 deinit 的時候,對它裡面的所有訂閱行為都呼叫 dispose() 方法
let disposeBag = DisposeBag()

// 第1個Observable,及其訂閱
let observable1 = Observable.of("A", "B", "C")
observable1.subscribe { event in
    print(event)
}.disposed(by: disposeBag)

// 第2個Observable,及其訂閱
let observable2 = Observable.of(1, 2, 3)
observable2.subscribe { event in
    print(event)
}.disposed(by: disposeBag)

特徵序列

Observable 是所有序列的核心基礎, 基於 Observable 新增一些特徵,使其滿足不同的場景或需求,同時使程式碼閱讀更加準確。

Single

Single 是 Observable 的另外一個版本。不像 Observable 可以發出多個元素,它要麼只能發出一個元素,要麼產生一個 error 事件。

  • 發出一個元素,或一個 error 事件
  • 不會共享狀態變化

一個比較常見的例子就是執行 HTTP 請求,然後返回一個應答或錯誤。不過你也可以用 Single 來描述任何只有一個元素的序列。

Observable 呼叫 .asSingle() 方法,將它轉換為 Single

Completable

它不像 Observable 可以發出多個元素,它要麼只能產生一個 completed 事件,要麼產生一個 error 事件。

  • 發出零個元素
  • 發出一個 completed 事件或者一個 error 事件
  • 不會共享狀態變化

Completable 適用於那種你只關心任務是否完成,而不需要在意任務返回值的情況。

它和 Observable<Void> 有點相似。

Maybe

它介於SingleCompletable 之間,它要麼只能發出一個元素,要麼產生一個 completed 事件,要麼產生一個 error 事件。

  • 發出一個元素或者一個 completed 事件或者一個 error 事件
  • 不會共享狀態變化

如果你遇到那種可能需要發出一個元素,又可能不需要發出時,就可以使用 Maybe

Driver

為簡化 UI 層的程式碼產生的序列

  • 不會產生 error 事件
  • 一定在 MainScheduler 監聽(主執行緒監聽)
  • 共享狀態變化

通過 .asDriver 方法將 ControlProperty 轉換為 Driver

ControlEvent

專門用於描述 UI 控制元件所產生的事件,它具有以下特徵:

  • 不會產生 error 事件
  • 一定在 MainScheduler 訂閱(主執行緒訂閱)
  • 一定在 MainScheduler 監聽(主執行緒監聽)
  • 共享狀態變化