RxSwift 使 Observable 触发一个主题
RxSwift Make Observable trigger a subject
我有一个 BehaviorSubject
,其中我的 tableview 通过 RxDataSources 绑定。
除此之外,我有一个 pull to refresh,它创建一个 observable 来更新数据并更新 BehaviorSubject
中的数据,以便我的 UITableView 正确更新。
现在的问题是,每当我的 API 调用失败时,我该如何处理错误处理?
我想到的几个选项是:
- 订阅观察者的
onError
,调用我的BehaviorSubject
\ 的onError
- 想办法
concat
?或 bind(to: ..)
- 除了我的 tableview 订阅
BehaviorSubject
之外,让我的 ViewController
中的另一个订阅者订阅。
有什么建议吗?
理想情况下,您根本不会使用 BehaviorSubject。来自 Intro to Rx 书:
The usage of subjects should largely remain in the realms of samples and testing. Subjects are a great way to get started with Rx. They reduce the learning curve for new developers, however they pose several concerns...
更好的方法是在您的 viewDidLoad 中执行类似的操作(或从您的 viewDidLoad 调用的函数):
let earthquakeData = Observable.merge(
tableView.refreshControl!.rx.controlEvent(.valueChanged).asObservable(),
rx.methodInvoked(#selector(UIViewController.viewDidAppear(_:))).map { _ in }
)
.map { earthquakeSummary /* generate URLRequest */ }
.flatMapLatest { request in
URLSession.shared.rx.data(request: request)
.materialize()
}
.share(replay: 1)
earthquakeData
.compactMap { [=10=].element }
.map { Earthquake.earthquakes(from: [=10=]) }
.map { [=10=].map { EarthquakeCellDisplay(earthquake: [=10=]) } }
.bind(to: tableView.rx.items(cellIdentifier: "Cell", cellType: EarthquakeTableViewCell.self)) { _, element, cell in
cell.placeLabel.text = element.place
cell.dateLabel.text = element.date
cell.magnitudeLabel.text = element.magnitude
cell.magnitudeImageView.image = element.imageName.isEmpty ? UIImage() : UIImage(named: element.imageName)
}
.disposed(by: disposeBag)
earthquakeData
.compactMap { [=10=].error }
.map { (title: "Error", message: [=10=].localizedDescription) }
.bind { [weak self] title, message in
self?.presentAlert(title: title, message: message, animated: true)
}
.disposed(by: disposeBag)
materialize()
运算符将 Event.error(Error)
结果转换为 Event.next(.error(Error))
,这样链就不会被破坏。 .compactMap { [=14=].element }
仅发出成功结果,而 .compactMap { [=15=].error }
仅发出错误。
以上代码改编自我的 RxEarthquake 示例。
我有一个 BehaviorSubject
,其中我的 tableview 通过 RxDataSources 绑定。
除此之外,我有一个 pull to refresh,它创建一个 observable 来更新数据并更新 BehaviorSubject
中的数据,以便我的 UITableView 正确更新。
现在的问题是,每当我的 API 调用失败时,我该如何处理错误处理?
我想到的几个选项是:
- 订阅观察者的
onError
,调用我的BehaviorSubject
\ 的 - 想办法
concat
?或bind(to: ..)
- 除了我的 tableview 订阅
BehaviorSubject
之外,让我的ViewController
中的另一个订阅者订阅。
onError
有什么建议吗?
理想情况下,您根本不会使用 BehaviorSubject。来自 Intro to Rx 书:
The usage of subjects should largely remain in the realms of samples and testing. Subjects are a great way to get started with Rx. They reduce the learning curve for new developers, however they pose several concerns...
更好的方法是在您的 viewDidLoad 中执行类似的操作(或从您的 viewDidLoad 调用的函数):
let earthquakeData = Observable.merge(
tableView.refreshControl!.rx.controlEvent(.valueChanged).asObservable(),
rx.methodInvoked(#selector(UIViewController.viewDidAppear(_:))).map { _ in }
)
.map { earthquakeSummary /* generate URLRequest */ }
.flatMapLatest { request in
URLSession.shared.rx.data(request: request)
.materialize()
}
.share(replay: 1)
earthquakeData
.compactMap { [=10=].element }
.map { Earthquake.earthquakes(from: [=10=]) }
.map { [=10=].map { EarthquakeCellDisplay(earthquake: [=10=]) } }
.bind(to: tableView.rx.items(cellIdentifier: "Cell", cellType: EarthquakeTableViewCell.self)) { _, element, cell in
cell.placeLabel.text = element.place
cell.dateLabel.text = element.date
cell.magnitudeLabel.text = element.magnitude
cell.magnitudeImageView.image = element.imageName.isEmpty ? UIImage() : UIImage(named: element.imageName)
}
.disposed(by: disposeBag)
earthquakeData
.compactMap { [=10=].error }
.map { (title: "Error", message: [=10=].localizedDescription) }
.bind { [weak self] title, message in
self?.presentAlert(title: title, message: message, animated: true)
}
.disposed(by: disposeBag)
materialize()
运算符将 Event.error(Error)
结果转换为 Event.next(.error(Error))
,这样链就不会被破坏。 .compactMap { [=14=].element }
仅发出成功结果,而 .compactMap { [=15=].error }
仅发出错误。
以上代码改编自我的 RxEarthquake 示例。