理解 RxSwift:实现原理(二)

5,010 阅读4分钟

理解 RxSwift:为什么要使用 RxSwift(一)

理解 RxSwift:实现原理(二)

理解 RxSwift:MVVM(三)

理解 RxSwift:单元测试(四)

RxSwift 内部是如何运行的,Observable 与 Observer 之间存在什么关系,Operator 又是如何实现的,如果想彻底弄清楚 RxSwift,我们可以自己写一个简单的 RxSwift,帮助自己真正理解其实现原理,从而更好地使用 RxSwift 进行开发。

基本原理

RxSwift 是观察者模式的拓展版,但归根结底还是观察者模式。用户输入、点击事件、定时器、网络请求等都可以当成 Observable(被观察者),Observer(观察者)总会在 Observable 处注册一个订阅,当事件发生时,Observable 找到所有的订阅并通知观察者。

观察者模式

简单介绍下观察者模式,已经熟悉的可以跳过这一段。

当一个对象的状态发生变化时,所有依赖于它的对象都得到通知并做出反应。比如在 MVC 中,Model 就是观察者模式中的被观察者(Subject),View 是观察者模式中的观察者(Observer),当 model 发生改变里,触发通知监听它的 view 进行更新。

我们用 Swift 写一个简单的观察者:

//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 本质上是一个函数,接受一个订阅函数,当有事件发生时,触发这个订阅函数进行更新。

//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,只是简单地打印传入的内容。

函数 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原理解析之自己造一个