使用 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
中使用它来实现取消。
我有一个问题,不知道如何解决。
在我的 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
中使用它来实现取消。