RxSwift的个人笔记

最近在看电报项目 https://github.com/TelegramMessenger/Telegram-iOS.git 发现里面也是使用响应式编程,里面SSignalKit库来做事件触发和监听相关的内容。由于原来主要是用Object-C开发,对于Swift的骚气用法老是消化不良,看了一段时间,有一些明白了些的点需要记录下来。

 和RxSwift对比,个人觉得 SSignalKit 学习起来更好理解,看了一段时间,我发现了需要吐槽的点,RxSwift命名上面导致它不好吸收。

说明Single的两个主要方法(你会不会觉得SingleObserver应该换个名字,毕竟这不是用作观察者而是要主动发消息的):

// 用商家发货来举例, create是相当于定义了商品下单后的一些列流程。其中 SinglePoster 对象也就是 sendGoods 发货时执行的具体内容,业务侧通过SinglePoster来发货
public static func create(sendGoods: @escaping (@escaping SinglePoster) -> Disposable) -> Single<Element> { 
// 创建一个快递单,方法内给出一个闭包,让业务侧(商家)可以实现快递的发送(商家通过平台指定好的方式来发货)
        let goodsStream = Receiveable<Element>.create { poster in
     // 这里相当于创建了商品快递流,这个快递是通过快递员来送货的
           // 这里平台定义商家发货的具体方式,通过sendGoods这个闭包,给到商家
            return sendGoods { goods in
                switch goods {
                case .success(let box):
                    poster.send(.next(box)) // 商品准备好了,让快递员送货 (送货实际上是快递员在执行这项操作)
                    poster.send(.completed) // 快递员告知货物送达
                case .failure(let error):
                    poster.send(.error(error)) // 快递员告知快递单异常
                }
            }
        }
        
        return PrimitiveSequence(raw: goodsStream)
    }
// 下单并且开始监听快递单的进程,此处 SingleEvent 相当于快递的变化情况, Element 是具体变化内容
public func subscribe(_ observer: @escaping (SingleEvent<Element>) -> Void) -> Disposable {
        var stopped = false
        return self.primitiveSequence.asObservable().subscribe { event in
            // 这里是将快递员送货情况,上报给平台转为快递单变化情况,通知给到购买者
            if stopped { return }
            stopped = true
            
            switch event {
            case .next(let element):
                observer(.success(element)) // 订单完成,货物送达
            case .error(let error):
                observer(.failure(error)) // 送货失败,订单异常
            case .completed:
                rxFatalErrorInDebug("Singles can't emit a completion event")
            }
        }
    }

查看on方法顺着逻辑找到Observer对象:

这里Observer对象是在subscribe调用时创建的,创建时传入了一个闭包,这个闭包代表的就是监听到值改变时的响应处理 observer。同时 create 方法中使用到的 on 方法,也是通过这个对象来进行调用的。

/// A type-erased `ObserverType`.
///
/// Forwards operations to an arbitrary underlying observer with the same `Element` type, hiding the specifics of the underlying observer type.
public struct AnyObserver<Element> : ObserverType {
    /// Anonymous event handler type.
    public typealias EventHandler = (Event<Element>) -> Void

    private let observer: EventHandler

    /// Construct an instance whose `on(event)` calls `eventHandler(event)`
    ///
    /// - parameter eventHandler: Event handler that observes sequences events.
    public init(eventHandler: @escaping EventHandler) {
        self.observer = eventHandler
    }
    
    /// Construct an instance whose `on(event)` calls `observer.on(event)`
    ///
    /// - parameter observer: Observer that receives sequence events.
    public init<Observer: ObserverType>(_ observer: Observer) where Observer.Element == Element {
        self.observer = observer.on
    }
    
    /// Send `event` to this observer.
    ///
    /// - parameter event: Event instance.
    public func on(_ event: Event<Element>) {
        self.observer(event)
    }

    /// Erases type of observer and returns canonical observer.
    ///
    /// - returns: type erased observer.
    public func asObserver() -> AnyObserver<Element> {
        self
    }
}

这里可以看到,调用 on 方法时,即调用了 observer 这个闭包。

注意:

1. 我们create的时候,只是定义了相关的逻辑(此时并没有进行真正的调用),相当于定义了 subscribe 之后会进行怎么样的处理

2. 当我们进行 subscribe 时,才会进行下单,此时开始执行我们在create时定义的逻辑,也就是说每次 subscribe 都会跑一遍这块代码。

3. 当我们调用 subscribe 时,才会生成 observer 对象(也是上面说的 poster 对象),这样才能使create内的代码逻辑正确执行。

以下是说明示例:

 可以看出,同一个 Single 对象,调用两次 subscribe 是不同的。并且可以尝试不调用 subscribe 方法,那么 create 的函数体也不会执行,不会有任何打印。

Producer<Element>: Observable<Element>  实现 subscribe 方法,可订阅

Observer: ObserverType 实现 on 方法,可接收数据变化通知

Sink<Observer: ObserverType>: Disposable 持有 Observer 对象,给Observer对象传递消息,实现启动 (run方法)

创建 Producer 对象,定义好事务的逻辑

Producer 的 subscibe 方法传入 Observer 对象(Observer对象会持有收到消息后的逻辑处理闭包)。此时会调用 Producer 的 run 方法

Producer 的 run 方法(传入Observer对象)内部创建 Skin 对象,可以理解为一个具体的调控和执行者。

Sink 包装 Observer 对象,调用它自己的 run 方法,执行 Producer 创建时定义的函数闭包(传入可触发Observer对象 on 方法的对象),并且 Skin 的 on 方法实现了消息传递给到 Observer

将结束监听的方法调用,封装为 SinkDisposer 对象,包含了任务销毁涉及对象的相关的 dispose 方法调用 

 

create等创建数据初始化和变化的逻辑,辅助一些过滤、转换的方法,在后面进行最终subscribe

posted @ 2024-03-28 15:49  雨筱逸悠  阅读(9)  评论(0编辑  收藏  举报