使用 RxSwift 的异步任务和多个观察者
Posted
技术标签:
【中文标题】使用 RxSwift 的异步任务和多个观察者【英文标题】:Async task and multiple observers with RxSwift 【发布时间】:2018-10-23 11:27:52 【问题描述】:我有一个问题,不知道如何解决。
在我的 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 $0.sections
public func getDiagnostics() -> Observable<String?>
return self.details().map $0.diagnostics
private func details() -> Observable<Disease>
return Observable.of(
self.disease.asObservable(),
self.diseaseDetails.take(1)
).merge()
但是, 在这个例子中提出了两个请求。我只需要一个请求即可获得许多订阅。有什么想法吗?
【问题讨论】:
【参考方案1】:一个答案...
为了保证只有一个网络请求,你需要通过调用 .share()
来使 Observable 成为热的。在这种情况下,您可能还希望将其设置为重播,因此 .share(replay: 1)
。但是,请记住,这意味着diseaseDetails
只会提出一个请求,然后在每次被询问时吐出该响应。以您当前的代码结构方式,这意味着无需刷新。
解释...
流的工作方式是,当您订阅 Observable 时,订阅会沿着流一直向上到达源,并调用您提供给 create
函数的闭包。因此,默认情况下,每个订阅都会调用包含 SAPI.get()...
函数的闭包(这称为“冷”可观察对象。)但是,还有其他创建可观察对象的方法和短路方法这种行为。当这种情况发生时,Observable 被认为是“热的”。 .share()
运算符就是其中一种方式。当第一个订阅请求进来时,它会订阅上游的 Observable,但是对于任何后续的订阅请求,它只会将新的观察者添加到其列表中,并将任何后续响应发送给新的观察者。如果您告诉操作员“重播:n”,它将存储来自上游可观察对象的最后一个 n
事件,并在新订阅者连接时立即将它们发送给他们。
还有一些建议……
您明确忽略了网络请求的结果(_ = SAPI.get()...
代码)。该函数的结果很可能是一个允许您取消请求的对象,因此应该在您的Disposables.create
中使用以实现取消。
【讨论】:
谢谢。我用“share”替换了我的代码,并在 dispose 时取消了请求。 我对我的样本有一个问题。如果我想手动刷新 api 调用并且需要“共享”,如何更改此代码? 您需要详细说明您想要发出网络请求的所有原因,并将每个原因包装在一个 Observable 中。 (例如,refreshButton.rx.tap
、myViewController.rx.methodInvoked(#selector(viewDidAppear(_:)))
)然后将它们合并在一起并通过网络调用 flatMap。查看我的示例代码:github.com/dtartaglia/RxEarthquake以上是关于使用 RxSwift 的异步任务和多个观察者的主要内容,如果未能解决你的问题,请参考以下文章
前端基本知识:JS的异步模式:1回调函数;2事件监听;3观察者模式;4promise对象