ios - 如何使用 RxSwift 在订阅中执行订阅?
问题描述
目前我有以下工作代码:
mainView.saveButton.rx.tap.bind { [weak self] in
if let self = self {
// start indicator
self.viewModel.save() // Completable
.subscribe(onCompleted: { [weak self] in
// completed
}, onError: { error in
// error
})
.disposed(by: self.disposeBag)
}
}.disposed(by: disposeBag)
但我知道这不是一个好方法(由于嵌套订阅),所以我正在尝试创建等效的工作(现在没有成功):
mainView.saveButton.rx.tap
.do(onNext: { [weak self] in
// start indicator
})
.flatMapFirst { _ in
self.viewModel.save() // Completable
}
.subscribe(onError: { error in
// error
}, onCompleted: { [weak self] in
// completed
})
.disposed(by: disposeBag)
订阅关闭根本没有调用。为什么?
解决方案
在flatMap
其源(按钮点击)完成之前不会完成。不能,因为如果用户再次点击按钮,它必须准备好。
解决此问题的最常见方法是让您的save()
函数返回 aSingle<Void>
而不是 a Completable
。如果您不想(或不能)这样做,那么您可以使用andThen
在完成时发送事件。
此外,您不希望出现错误来逃避 flatMap,因为这会破坏按钮点击。这意味着您需要catch
任何错误并将它们转换为闭包中的下一个事件。您可以使用materialize()
或catch
使用专门的主题来做到这一点。(例如,查看我的ErrorRouter。)
像这样的东西:
let errorRouter = ErrorRouter()
let saveSuccessful = mainView.saveButton.rx.tap
.flatMap { [viewModel] in
viewModel.save()
.andThen(Observable.just(()))
.rerouteError(errorRouter)
}
Observable.merge(
mainView.saveButton.rx.tap.map(to: true),
saveSuccessful.map(to: false)
)
.bind(onNext: { isIndicatorVisible in
// handle indicator
})
.disposed(by: disposeBag)
errorRouter.error
.bind(onNext: { error in
// handle error
})
.disposed(by: disposeBag)
推荐阅读
- javascript - 模态不适用于一系列按钮
- jquery - 如何根据所需规则(而不是其名称或索引)重新排序 JSON?
- python - 如何在 Django 中处理来自 HTML 的使用“Post”或“GET”方法提交的文本?
- matlab - 在 Matlab 中随机连接 wav 文件
- javascript - 使用 jquery 动态更改下拉列表的内容
- reactjs - 没有重载匹配此调用。React 中的 Typescript 和 StyledComponents
- scala - Scala spark - 从行中设置的列构造结构数组
- c# - 在电子邮件中包含授权标头
- php - 数组不会打印行数据
- python - Pandas 无法正常工作,即使我安装了它