如何在后台执行 RxSwift?

How to perform RxSwift in the background?

我试图在 table 行选择时在后台执行复杂的计算,但它冻结了 UI。请查看我的代码并告诉我可能有什么问题。

tableView.rx
    .modelSelected(Sring.self)
    .flatMap { item -> Observable<String> in
        
        for _ in 1...2_500 {
            for _ in 1...1_000 {
                
            }
        }
        return Observable.just("Hello world!")

    }
    .subscribeOn(ConcurrentDispatchQueueScheduler(qos: .background))
    .observeOn(MainScheduler.instance)
    .retry()
    .subscribe(onNext: { value in
        print(value)
    })
    .disposed(by: bag)

首先要理解此代码的是 subscribeOn 确定将在哪个线程上调用可观察对象的事件生成器,而不是将在哪个线程上发出值。如果源 Observable 在它订阅的同一个线程上发射,那么你的代码就可以工作(例如,如果你使用 Observable.just(_:)。但是 modelSelected 发射 在主线程上,无论它在哪个线程上订阅。flatMap 运算符在其源发出的线程上调用其闭包,因此也在主线程上。

所有这一切的结果是调用 subscribeOn(_:) 很少有用。只有当最终来源(最上游的那个)Observable 的生成器是一个同步的、阻塞的函数时,它才会真正按照你的期望去做。 (tableView.rx.modelSelected(String.self) 不是这种情况)

在这种情况下,您想要的更像是:

tableView.rx.modelSelected(String.self)
    .observeOn(ConcurrentDispatchQueueScheduler(qos: .background))
    .flatMap { item -> Observable<String> in
        sleep(3)
        return Observable.just("Hello world!")
    }
    .retry()
    .observeOn(MainScheduler.instance)
    .subscribe(onNext: { value in
        print(value)
    })
    .disposed(by: bag)