RxSwift - ObserveOn VS SubscribeOn

18 篇文章 0 订阅

Observable subscription


首先了解一下Observable subscription的工作情况,我们可以把订阅分为以下3个部分:


1)首先我们定义一个Observable,在某些情况下我们会在闭包内提供一些代码,该部分代码会执行相应的工作并且发送值(elements)给任意的观察者(observer)。当我们使用create操作符创建了该Observable,闭包内的代码就被存储起来用于后续的执行,而不是马上执行。如果当前没有观察者(observer),那么Observable仅仅是等待被订阅,不会执行任何操作。

2)当我们使用不同的操作符(operators)来处理被发送的值(elements),比如像:map,filter等等,这时候闭包仍然没有执行任何操作,我们这里仅仅是对Observable进行了部分的转换和过滤,相当于创建了一个更特别的Observable,而不是最初的Observable。

3)一直到我们调用subscribe(...)方法,这时候Observable开始工作起来。调用subscribe(...)方法将执行我们之前在闭包中所编写的代码。


对于上面的内容,有俩点需要明白:

1)订阅部分的代码(subscription code),该部分内容是位于上图的Observable.create{...}中的代码,在我们调用subscribe()之后会执行代码并产生值(elements)

2)观察部分的代码(observation code),是我们观察到被发送值(elements)的地方,这部分代码,我们经常使用,如:onNext: {...}, onCompleted: {...}等,这些地方就是我们进行观察中的地方。



Schedulers

RxSwift为我们提供了大量的预先定义的观察者,并且能够满足我们大多数时候的使用。官方的内容请看这里。 在这里我们只需要使用两个:

1)MainScheduler.instance,它保证scheduler工作在主线程(main thread)

2)ConcurrentDispatchQueueScheduler是使用GCD执行给定列队的工作


Subscribing and subscribeOn

现在了解一下subscribeOn操作符,它允许我们改变订阅部分代码(subscription code)将被执行的线程scheduler.



默认情况下订阅部分的代码(subscription code)将被跟你调用subscribe()方法在同一个线程,除非我们使用subscribeOn进行切换线程。例如:

Observable<Int>.create { observer in
            observer.onNext(1)
            sleep(1)
            observer.onNext(2)
            return Disposables.create()
            }
            .subscribe(onNext: { el in
                print(Thread.isMainThread)
            }).disposed(by: disposeBag)
如果我们把这部分代码放到viewDidLoad中,我们将看到会阻塞主线程,因为订阅部分代码中使用了sleep函数。我们的onNext代码中将打印出两个true,因为我们一直处于主线程。即主线程进行订阅,主线程创建observable,主线程执行onNext。

[main] subscribe() -> [main] creat {...} -> [main] onNext {...}
现在我们改变订阅(subscription)的scheduler,插入subscribeOn操作符

  Observable<Int>.create { observer in
            observer.onNext(1)
            sleep(1)
            observer.onNext(2)
            return Disposables.create()
            }
            .subscribeOn(ConcurrentDispatchQueueScheduler(qos: .background))
            .subscribe(onNext: { el in
                print(Thread.isMainThread)
            }).disposed(by: disposeBag)
这里将打印俩次false,因为我们将主线程转换到了后台线程。

[main] subscribe() -> [background] creat {...} -> [background] onNext {...}


Observing and observeOn

现在我们来看看观察序列中值(elements)的部分,如下图所示:


在上面的例子中,我们转换了订阅到后台线程列队,但是很多时候,我们想在onNext {...}中更新UI,所以需要回到主线程,那么这里我们就可以使用observerOn,如下:

Observable<Int>.create { observer in
            print(Thread.isMainThread)
            observer.onNext(1)
            sleep(1)
            observer.onNext(2)
            return Disposables.create()
            }
            .observeOn(MainScheduler.instance)
            .subscribeOn(ConcurrentDispatchQueueScheduler(qos: .background))
            .subscribe(onNext: { el in
                print(Thread.isMainThread)
            }).disposed(by: disposeBag)
代码执行结果为,false -> true -> true,observeOn和 subscribeOn的先后顺序没什么关系。代码执行顺序如下:

[main] subscribe() -> [background] creat {...} -> [main] onNext {...}

以上内容参考这里,官方相关介绍这里。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值