?RxSwift(二)Observable 与 柯里化

柯里化是避免地狱式回调的核心,也是了解Rx的核心

什么是柯里化

把一个函数作为另一个函数的参数。

    func simulate(){
        Observable { i in
            print(i)
        }
    }
    
    func Observable(observer: (Int)->Void){
        observer(3)
        observer(4)
        observer(5)
        observer(6)
    }
复制代码

simulate()函数中的那个闭包就是Observable函数的参数。

网上关于柯里化的优势解释的差强人意,甚至有些纯属是为了解释而解释。

我这里有个观点,欢迎大家批评:

柯里化的好处是,被调用函数有一定的可变性,自主性。因为它可以自主决定如何向调用者反向传参。

模拟Rx的核心

Observable函数中如果换成一个类,那他就更像是Rx的形式了

理解了这30行代码,对于理解Rx核心十分关键,当你理解上述的柯里化后你会发现不过如此。

enum Event {
    case next(Int)
}

class Observer {
    
    // 处理事件的闭包
    private let _handler: (Event) -> Void
    
    init(handler: @escaping (Event) -> Void) {
        _handler = handler
    }
    
    // 实现 监听事件 的协议,内部处理事件
    func on(event: Event) {
        // 处理事件
        _handler(event)
    }
}

class Observable{
    // 定义 发布事件 的闭包
    private let _eventGenerator: (Observer) -> Void
    
    init(eventGenerator: @escaping (Observer) -> Void) {
        _eventGenerator = eventGenerator
    }
    
    // 实现 订阅操作 的协议,内部发布事件
    func subscribe(observer: Observer){
        // 生成事件
        _eventGenerator(observer)
    }
}
复制代码

Observable其实就是个桥梁, eventGenerator保存Observable创建时外界传入的函数,subscribe执行时,eventGenerator执行外界函数。

有个特别的地方是这里的@escaping (Observer) -> Void Observer是一个类。

这时单独来看Observer也是一个桥梁,和Observable本质有这异曲同工之妙。

何其巧妙的结构:Observable(Observer(T)-> Void)。能设计出来的可能是天才吧。

使用:



class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let observable = Observable{ (observer) in
            observer.on(event: .next(0))
            observer.on(event: .next(1))
        }

        let observer = Observer{ (event) in
            switch event {
            case .next(let value):
                print("recive \(value)")
            }
        }

        observable.subscribe(observer: observer)
        
    }
}
复制代码

回调地狱

因为ObservableObserverObservable(Observer(T)-> Void)这种组合的存在,她能将所有的函数最后的结果返回到最上层,即函数调用层。内部自己处理各种情况,尤其是耗时问题(这一点会在后续实战时见到)。

我们发现本来的地狱回调编程了监控。依赖式问题,并发式问题在Rx面前也变成了小弟弟。

funcA{
    funcB{
        funcC{
            funcD{
                funcE{
    
                }
            }
        }
    }
}
复制代码

变成了

ObserverableA.flatMapLast{
    return ObserverableB
}.flatMapLast{
    return ObserverableC
}.flatMapLast{
    return ObserverableD
}.flatMapLast{
    return ObserverableE
}.subscribe{

}
复制代码

flatMapLast是一个操作符,后续会介绍到。

地狱式回调中还需要处理各种case,一旦忘记某个case,忘记写回调就会出现各种问题,而且编译器检测不出来。

但是Rx的这种写法,如果忘记return,会被提醒的,不会出现忘记case的情况,优点很明显了吧。

参考文章

# RxSwift 核心实现原理 – 楚权的世界 解析的十分透彻

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享