[英]RXSwift Not subscribing on Main Thread
我正在尝试进行多次 API 调用并填充 Realm 数据库。 一切正常。 但是,当我尝试在subscribe()
方法上运行performSegue()
时,会引发异常,通知我不能在后台线程上执行此操作,这是完全合理的。
但是因为我订阅了MainScheduler.instance
, subscribe()
方法不应该在 UI 线程上运行吗?
Single.zip(APIClient.shared.getSchools(), APIClient.shared.getPointsOfInterest())
.observeOn(SerialDispatchQueueScheduler(qos: .background))
.flatMap { zip in return Single.zip(SchoolDao.shared.insertSchools(schoolsJson: zip.0), PointOfInterestDao.shared.insertPointsOfInterest(poisJson: zip.1))}
.flatMap{ _ in Single.zip(SchoolDao.shared.countSchools(), PointOfInterestDao.shared.countPointsOfInterest())}
.subscribeOn(MainScheduler.instance)
.subscribe(onSuccess: { tableCounts in
let (schoolsCount, poisCount) = tableCounts
if(schoolsCount != 0 && poisCount != 0){
print(Thread.isMainThread) //Prints False
self.performSegue(withIdentifier: "splashToLogin", sender: nil)
}
}, onError: {
error in return
}).disposed(by: disposeBag)
我是否对 RXSwift 的工作原理做出了错误的假设?
编辑:如果我在.observeOn(MainScheduler.instance)
.subscribeOn(MainScheduler.instance)
订阅方法在主线程上运行。 这是正确的行为吗? .subscribeOn(MainScheduler.instance)
到底在做什么?
您的编辑说明了一切。 您最初对 subscribeOn 和 observeOn 的假设是倒退的。
subscribeOn
运算符是指链中运算符上方的可观察对象如何订阅事件源(并且在任何情况下都可能不会按照您的想法进行操作。您的 two.network 调用可能会设置自己的后台线程以发出值,无论它们是如何订阅的。)
例如,看看这个:
extension ObservableType {
func subscribeOnMain() -> Observable<Element> {
Observable.create { observer in
let disposable = SingleAssignmentDisposable()
DispatchQueue.main.async {
disposable.setDisposable(self.subscribe(observer))
}
return disposable
}
}
}
这使得该运算符为何称为 subscribeOn 变得显而易见。 这是因为订阅发生在有问题的调度程序/线程上。 这有助于您更好地理解当您堆叠 subscribeOn 运算符时发生了什么......
observeOn
运算符指的是将向观察者发射元素的调度程序(这是传递给subscribe
运算符的代码块。)
这看起来像这样:
extension ObservableType {
func observeOnMain() -> Observable<Element> {
Observable.create { observer in
self.subscribe { event in
DispatchQueue.main.async {
observer.on(event)
}
}
}
}
}
从这里您可以看到订阅是在原始调度程序上进行的,而观察者是在新调度程序上调用的。
这是一篇解释整个事情的好文章: http://rx-marin.com/post/observeon-vs-subscribeon/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.