RxSwift 使 Observable 触发一个主题
Posted
技术标签:
【中文标题】RxSwift 使 Observable 触发一个主题【英文标题】:RxSwift Make Observable trigger a subject 【发布时间】:2020-05-24 14:47:30 【问题描述】:我有一个BehaviorSubject
,我的 tableview 通过 RxDataSources 绑定到。
除此之外,我还有一个拉动刷新,它创建了一个可观察的更新数据并更新 BehaviorSubject
中的数据,以便我的 UITableView 正确更新。
现在的问题是,每当我的 API 调用失败时,我该如何处理错误处理?
我想到的几个选项是:
-
订阅观察者的
onError
,拨打我的BehaviorSubject
的onError
\
以某种方式尝试concat
?或bind(to: ..)
让我的ViewController
中的另一个订阅者订阅,除了我的tableview 订阅BehaviorSubject
。
有什么建议吗?
【问题讨论】:
【参考方案1】:理想情况下,您根本不会使用 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示例。
【讨论】:
以上是关于RxSwift 使 Observable 触发一个主题的主要内容,如果未能解决你的问题,请参考以下文章
RxSwift:多次连接到 Connectable Observable
在 RxSwift 中,我如何对 observable 未发送任何事件进行单元测试?