RxSwift序列转换
map
将序列每个元素转换一遍,适合于序列内的元素类型改变,比如Bool转换为String, 或者其他值的操作。
输入类型, 输出还是类型
flapMap
将序列的元素转换为其他序列, 就很适合a序列转换为b序列,比如
输入类型/序列, 输出序列
flapMapLatest
和flapMap相似,不同的是只发出最新元素
Error 序列中断
一旦序列产生一个error,整个序列将被终止,后续监听也就监听不了,也包括序列转换
Error Handling 错误事件处理
实例代码:
private func createObservable() {
let subject = PublishSubject<Void>()
/// 使用flatMap转换为其他序列
let otherOb = subject.asObservable()
.flatMapLatest({_ -> Observable<String> in
print("flatMap")
return self.netRequest()
})
// 发出一次next, 由于没有订阅,所以没有效
subject.onNext(())
// 订阅
subject.subscribe(onNext: { (_) in
print("发出一次事件")})
.disposed(by: disposeBag)
// 又发出一次事件
subject.onNext(())
// 订阅otherOb, 之后发出的事件都可以监听,除非序列发出Error事件
otherOb.subscribe(onNext: { (value) in
print("otherSub subscribe")
print(value)})
.disposed(by: disposeBag)
// subject 发出两次事件
subject.onNext(()) // [1]如果在netRequet方法中抛出Error, 就会引起序列终止,下面一个发出事件也就无效。
subject.onNext(())
}
// 模拟网络请求
private func netRequest() -> Observable<String> {
return Observable<String>.create { (observer) -> Disposable in
observer.onError(NSError(domain: "www.baidu.com", code: 30, userInfo: [:]))
// observer.onNext("你好")
// observer.onCompleted()
return Disposables.create()
}
}
运行日志打印
发出一次事件
发出一次事件
flatMap
Unhandled error happened: Error Domain=www.baidu.com Code=30 "(null)"
subscription called from:
发出一次事件
发出一次事件
可以看到,如果网络请求抛出error [1]之后的下一次next将不会转换,同理转换出来的序列也会中断。
如果不发出Error只发出next和complete
// 模拟网络请求
private func netRequest() -> Observable<String> {
return Observable<String>.create { (observer) -> Disposable in
observer.onNext("你好")
observer.onCompleted()
return Disposables.create()
}
}
打印输出
发出一次事件
发出一次事件
flatMap
otherSub subscribe
你好
发出一次事件
flatMap
otherSub subscribe
你好
可以看到,序列没有中断,对应的转换也没有中断。
总之
不要轻易发出Error事件,考虑到会不会终止序列和转换。如果需要错误提示,采用Result也许更好。