理解 RxSwift:實現原理(二)

理解 RxSwift:爲何要使用 RxSwift(一)git

理解 RxSwift:實現原理(二)github

RxSwift 內部是如何運行的,Observable 與 Observer 之間存在什麼關係,Operator 又是如何實現的,若是想完全弄清楚 RxSwift,咱們能夠本身寫一個簡單的 RxSwift,幫助本身真正理解其實現原理,從而更好地使用 RxSwift 進行開發。api

基本原理

RxSwift 是觀察者模式的拓展版,但歸根結底仍是觀察者模式。用戶輸入、點擊事件、定時器、網絡請求等均可以當成 Observable(被觀察者),Observer(觀察者)總會在 Observable 處註冊一個訂閱,當事件發生時,Observable 找到全部的訂閱並通知觀察者。bash

觀察者模式

簡單介紹下觀察者模式,已經熟悉的能夠跳過這一段。網絡

當一個對象的狀態發生變化時,全部依賴於它的對象都獲得通知並作出反應。好比在 MVC 中,Model 就是觀察者模式中的被觀察者(Subject),View 是觀察者模式中的觀察者(Observer),當 model 發生改變裏,觸發通知監聽它的 view 進行更新。閉包

咱們用 Swift 寫一個簡單的觀察者:app

//Observer pattern
protocol Observer {
    func update(message: String)
}

class Subject {
    var observers: Array<Observer> = []
    
    func register(observer:Observer) {
        self.observers.append(observer)
    }
    
    func notify(message: String) {
        for observer in observers {
            observer.update(message: message)
        }
    }
}
class Observer1: Observer {
    func update(message: String) {
        print("Observer1: " + message)
    }
}

class Observer2: Observer {
    func update(message: String) {
        print("Observer2: " + message)
    }
}
複製代碼

被觀察者 Subject 類內部存儲了訂閱它的對象,當 Subject 有更新時,就會通知這些訂閱的 Observer。函數

let subject = Subject()
let observer1 = Observer1()
let observer2 = Observer2()

subject.register(observer: observer1)
subject.register(observer: observer2)

subject.notify(message: "zcj")
複製代碼

Observable

Observable 本質上是一個函數,接受一個訂閱函數,當有事件發生時,觸發這個訂閱函數進行更新。post

//simple 1: Observable
typealias EventHandler = (String) -> Void

func myObservable(eventHandler: EventHandler) {
    eventHandler("zcj")
    eventHandler("hello")
    eventHandler("world")
}

let eventHandler : EventHandler = {(value) -> Void in
    print(value)
}
myObservable(eventHandler: eventHandler)
複製代碼

上面定義了一個閉包 EventHandler,傳入一個 String 參數,無返回值。實例化一個閉包對象 eventHandler,只是簡單地打印傳入的內容。ui

函數 myObservable,接收一個閉包,並根據須要調用這個閉包。

Observer

咱們把 Observable 封裝成一個類,這樣能夠很方便地把 Observer 當作匿名對象傳進去,以一種簡單的方式來使用,先看最終的使用方式

let observable = Observable{(observer) -> Void in
    observer.next(value: "zcj")
}

let closure = {(value: String) -> Void in
    print(value)
}
observable.subscribe(eventHandler: closure)
複製代碼

爲了實現這個效果,首先把訂閱函數封裝進 Observer 類,增長一個 next 函數,next 函數被調用時,執行 Observer 所持有的訂閱函數。

//simple 2:Observer
class Observer {

    typealias EventHandler = (String) -> Void

    private let _eventHandler : EventHandler
    init(eventHandler: @escaping EventHandler) {
        self._eventHandler = eventHandler
    }

    func next(value: String) {
        self._eventHandler(value)
    }
}

func myObservable(handle: @escaping (String) -> Void) {
    let observer = Observer(eventHandler: handle)
    observer.next(value: "zcj")
}

let closure = {(value: String) -> Void in
    print(value)
}
myObservable(handle: closure)
複製代碼

Observable 也包裝成類,經過 subscribeHandler 把 Observer 之內在的形式建立

//simple 3
typealias EventHandler = (String) -> Void
typealias SubscribeHandler = (Observer) -> Void

class Observer {
    private let _eventHandler : EventHandler
    init(eventHandler: @escaping EventHandler) {
        self._eventHandler = eventHandler
    }

    func next(value: String) {
        self._eventHandler(value)
    }
}

class Observable {

    private let subscribeHandler: SubscribeHandler

    public init(_ subscribeHandler: @escaping SubscribeHandler) {
        self.subscribeHandler = subscribeHandler
    }

    public func subscribe(eventHandler: @escaping EventHandler) {
        let observer = Observer(eventHandler: eventHandler)
        self.subscribeHandler(observer)
    }
}

let observable = Observable{(observer) -> Void in
    observer.next(value: "zcj")
}

let closure = {(value: String) -> Void in
    print(value)
}
observable.subscribe(eventHandler: closure)
複製代碼

Operator

RxSwift 中的操做符實際上是一個接收源 Observable,而後加工處理後返回一個新的 Observable,咱們實現一個簡單的 map 操做符,代碼以下:

//simple 4

typealias EventHandler = (String) -> Void
typealias SubscribeHandler = (Observer) -> Void

class Observer {

    private let _eventHandler : EventHandler
    init(eventHandler: @escaping EventHandler) {
        self._eventHandler = eventHandler
    }

    func next(value: String) {
        self._eventHandler(value)
    }
}

class Observable {

    private let subscribeHandler: SubscribeHandler

    public init(_ subscribeHandler: @escaping SubscribeHandler) {
        self.subscribeHandler = subscribeHandler
    }

    public func subscribe(eventHandler: @escaping EventHandler) {
        let observer = Observer(eventHandler: eventHandler)
        self.subscribeHandler(observer)
    }
}

func map(source: Observable, transform: @escaping (_ value: String) -> String) -> Observable {
    return Observable({ (observer) in
        let closure = {(value: String) -> Void in
            let transformedValue = transform(value)
            observer.next(value: transformedValue)
        }
        source.subscribe(eventHandler: closure)
    })
}

let observable = Observable{(observer) -> Void in
    observer.next(value: "zcj")
}

let closure = {(value: String) -> Void in
    print(value)
    print(value)
    print(value)
}

map(source: observable) { (value) -> String in
    return "hi " + value
}.subscribe(eventHandler: closure)
複製代碼

在 map 內部,根據外層傳進來的閉包 transform 處理生成一個新的 Observable。

在新的 Observable 內部,建立一個閉包將 value 轉換成 transformedValue,原始的 sourec 訂閱這個閉包,當監聽到外層數據傳進來,通知內部 observer 進行更新。

本文 Demo:github.com/superzcj/Rx…

總結

首先咱們從理論上介紹了 RxSwift 基本原理,而後用 Swift 實現了 RxSwift 的基礎:觀察者模式,最後分別實現了 Observable、Observer 和 Operator。

以上都屬於 RxSwift 的核心,咱們完整實現一遍,相信在這個過程當中,你們會對 RxSwift 有一個更深入的認識,同時也能更好地運用 RxSwift 進行開發。

下一篇咱們將介紹 RxSwift 如何結合 MVVM,更好地服務咱們的業務開發。

參考資料

rxjs原理解析之本身造一個

相關文章
相關標籤/搜索