美文网首页
理解 RxSwift:实现原理(二)

理解 RxSwift:实现原理(二)

作者: 潇潇潇潇潇潇潇 | 来源:发表于2019-06-10 13:45 被阅读0次

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

    理解 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:https://github.com/superzcj/RxSwiftDemo

    总结

    首先我们从理论上介绍了 RxSwift 基本原理,然后用 Swift 实现了 RxSwift 的基础:观察者模式,最后分别实现了 Observable、Observer 和 Operator。

    以上都属于 RxSwift 的核心,我们完整实现一遍,相信在这个过程中,大家会对 RxSwift 有一个更深刻的认识,同时也能更好地运用 RxSwift 进行开发。

    下一篇我们将介绍 RxSwift 如何结合 MVVM,更好地服务我们的业务开发。

    参考资料

    rxjs原理解析之自己造一个

    相关文章

      网友评论

          本文标题:理解 RxSwift:实现原理(二)

          本文链接:https://www.haomeiwen.com/subject/utkzxctx.html