使用 RxSwift 的异步任务和多个观察者

Async task and multiple observers with RxSwift

我有一个问题,不知道如何解决。

在我的 ViewModel 中,我有一个带值的 Observable 字段。

self.diseaseDetails = Observable<Disease>.create { (observer) -> Disposable in

            _ = SAPI.get().diseases(diseases: 5, success: { (disease) in
                observer.on(.next(disease))
                observer.on(.completed)

            }) { (failedMessage) in
                observer.on(.completed)
            }

            return Disposables.create()
        }

然后像这样从 observable 获取数据:

public func getSections() -> Observable<String?> {
        return self.details().map { [=11=].sections }
    }

    public func getDiagnostics() -> Observable<String?> {
        return self.details().map { [=11=].diagnostics }
    }

private func details() -> Observable<Disease> {

        return Observable.of(
            self.disease.asObservable(),
            self.diseaseDetails.take(1)
        ).merge()
    }

但是, 本例中提出了两个请求。对于许多订阅,我只需要一个请求。有什么想法吗?

一个答案...

为了保证只有一个网络请求,需要通过调用.share()使Observable热起来。在这种情况下,您可能还想将其设置为重播 .share(replay: 1)。但是,请记住,这意味着 diseaseDetails 只会发出一个请求,然后在每次被询问时吐出该响应。按照您当前组织代码的方式,这意味着没有刷新。

一个解释...

流的工作方式是,当您订阅一个 Observable 时,订阅沿着流一直上升到源,它调用您给 create 函数的闭包。所以默认情况下,每个订阅调用包含你的SAPI.get()...函数的闭包(这被称为“冷”可观察对象。)但是,还有其他创建可观察对象的方法,并且短路这种行为的方法。当发生这种情况时,Observable 被认为是“热的”。 .share() 运算符就是其中一种方式。当第一个订阅请求进来时,它会订阅上游的 Observable,但对于任何后续的订阅请求,它只会将新的观察者添加到它的列表中,并将任何后续响应发送给新的观察者。如果您告诉操作员“重播:n”,它将存储来自其上游可观察对象的最后 n 事件,并在新订阅者连接时立即将它们发送给他们。

还有一些建议...

您明确忽略了网络请求的结果(_ = SAPI.get()... 代码)。该函数的结果很可能是一个允许您取消请求的对象,因此应该在您的 Disposables.create 中使用它来实现取消。