我有一个BehaviorSubject
,通过RxDataSources绑定了我的表视图。
此外,我还需要刷新以创建一个可观察的对象,该对象可更新数据并更新BehaviorSubject
中的数据,以便我的UITableView正确更新。
现在的问题是,每当我的API调用失败时,如何处理错误处理?
我想到的几个选项是:
onError
并呼叫我的onError
的BehaviorSubject
\concat
?或bind(to: ..)
ViewController
中的另一个订阅者订阅,除了我的表视图订阅了BehaviorSubject
。 有什么建议吗?
理想情况下,您根本不会使用BehaviorSubject。从Intro to Rx书中:
主题的使用应很大程度上保留在样本和测试领域。主题是开始使用Rx的好方法。它们减少了新开发人员的学习难度,但是却带来了一些问题...
更好的方法是在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 { $0.element }
.map { Earthquake.earthquakes(from: $0) }
.map { $0.map { EarthquakeCellDisplay(earthquake: $0) } }
.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 { $0.error }
.map { (title: "Error", message: $0.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 { $0.element }
仅发出成功结果,而.compactMap { $0.error }
仅发出错误。
上面的代码改编自我的RxEarthquake示例。