RxSwit学习-02-序列的核心逻辑

973 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

我们之前学习了RxSwit 在编程的思想,以及在Swift中对我们常用控件等进行rx的使用,本文主要简单介绍RxSwit序列核心逻辑

1. 可观察序列 - Observable

Observable 序列可以是有限的也可以是无限的。比如我们的网络请求就是有限的,而定时器是无限的,一直不断产生变化。

image.png

  • 无穷序列
let ob1 = Observable<Int>.interval(1, scheduler: MainScheduler.instance)

比如我们创建于一个定时器,就是一个无穷的序列

  • 有穷序列
let ob2 = Observable.just([1,2,3])

        ob2.subscribe { (arr) in

            print(arr)

        } onError: { error in

            print(error)

        } onCompleted: {

            

            print("completed")

        } onDisposed: {

            

            print("disposed")

        }.disposed(by: disposeBag)

对于初始化数组就是订阅了它变化,以及序列完成销毁

image.png

  • 错误 对于错误的订阅,比如我们请求一个错误的网络请求
URLSession.shared.rx.response(request: URLRequest.init(url: URL.init(string: "www.baidu.xx")!))

            .subscribe(onNext: { (respose,data)in

                

            }, onError:{  (error) in

                

                print(error)

                

            }).disposed(by: disposeBag)

打印结果

image.png

不管是有穷的序列还是无穷的序列都是对序列创建,订阅,销毁

我们创建一个序列,查看它的流程

//1.创建

        let ob = Observable<Any>.create{ (obserber) -> Disposable in

            

            //3.发送信号

            obserber.onNext("hello")

            obserber.onError(NSError.init(domain: "NetWorkError", code: 400, userInfo: nil))

            //obserber.onCompleted()

            return Disposables.create()

            

        }

        //2.订阅

        

        ob.subscribe(onNext: { (value) in

            

            print(value)

            

        }, onError:{ (error) in

            

            print(error)

            

        } , onCompleted: {

            

            print("订阅完成")

        }, onDisposed: {

            print("订阅销毁")

        }).disposed(by: disposeBag)

这里onNext表示发送一次信号,onErroronCompleted是互斥的,都代表结束了序列,其流程和我们上面的图一样。

2. 序列的核心逻辑

2.1 创建序列

我们执行回调本质是闭包的调用,我们通过onNext()传值,执行下面的回调。我们查看create的创建

image.png

继续点击查看AnonymousObservable初始化

image.png

主要是一个初始化的构造方法run的实列方法,通过初始化保存我们传过来的闭包subscribeHandler

2.2 订阅序列

  • 继续看下subscribe

image.png

该方法传入一个闭包,返回一个DisposableDisposable是用于回收序列的,你可以在闭包onDisposed中传入,否则系统帮你创建。之后创建观察者observer,传入一个尾随闭包。该闭包中根据event枚举进行不同的回调。可以发现其中errorcomplete是会有disposable.dispose(),表示结束这个序列。

  • asObservable()

我们通过Observable<Any>.create创建了序列,之后通过subscribe创建了observer,那么他们怎么联系的呢?我们可以看到最后一句

return Disposables.create(

                self.asObservable().subscribe(observer),

                disposable

            )

对于asObservable()

image.png

协议ObservableConvertibleType中定义了这个方法,我们的Observable序列都遵循了这个协议

image.png

类似我们oc中类型的强制转换比如我们oc中的类都继承于NSObject那么我们子类都可以转换为NSObject

这里我们返回的self自身,也就是AnonymousObservable,也是Observable<E>的类型,因此我们可以使用subscribe方法。

  • subscribe(observer)

这里相当于我们把之前创建的序列通过subscribe观察者传递到了observe序列中,之后执行闭包中的回调,做到了你中有我,我中有里。只要发送event的事件就能触发回调,做到了响应式

image.png

我们之前在序列AnonymousObservable中没有发现 subscribe的实现方法,但是它继承父类Producer

  • Producer

image.png

重写了Observale的subscribe的方法,里面调用自身run方法,传入我们外面传入的观察者observer。先创建一个AnonymousObservableSink对象并持有observer,然后调用这个对象的run方法把self传递过去,也就是把observable作为参数AnonymousObservableSink这个类将可观察者Observable和观察者Observer链接起来,实现事件的传递,起到一个桥梁的作用。

image.png

  • sink.run ,通过业务下沉,让分工更加明确

image.png

这里会回调我们之前创建序列observe的回调,因此在首次订阅的时候会触发序列的回调。继续看AnyObserver(self)

image.png

这里初始化构造的时候,我们创建了一个结构体 AnyObserver 保存了一个信息 AnonymousObservableSink .on 函数

image.png

保存了我们的AnonymousObserver的event事件

2.3 发送信号

通过上面的分析可知,在订阅的时候会走一次subscribeHandler的回调。我们之前在里面调用了 obserber.onNext("hello")

image.png

里面先调用了AnyObserver遵循协议的on方法,也就是回调了event事件,我们在event的事件中传递了.next,并带有我们的参数element。我们的on方法来做AnonymousObservableSink.on 因此会进入下面的方法

image.png

self.forwardOn(event) 这也是执行的核心代码,因为 AnonymousObservableSink 继承 Sink 这里还有封装

image.png

其中 self._observer 就是我们初始化保存的 观察者:AnonymousObserver,也就是最后会调用我们初始化AnonymousObserver的时候的闭包回调

image.png

3. 总结

序列创建的时候,创建匿名序列AnonymousObservable,保存subscribeHandler。序列进行subscribe订阅的时候创建观察者AnonymousObserver并保存eventHandler,调用run方法进行subscribeHandler的回调。发送信号则通过onNext()等调用观察者AnonymousObserveronCore进行_eventHandler(event)事件回调。流程图如下所示:

未命名文件.jpg