![](/img/trans.png)
[英]RxSwift - How to handle different error scenarios with Observable.zip
[英]rxswift error handle issue
我在视图模型中有一个名为createObservable
的BehaviorSubject
。 我的视图控制器订阅它。
viewModel!.createObservable.subscribe(onNext: {[unowned self] (obj:PassbookModelType?) -> Void in
if let _ = obj{
self.dismissVC()
}
}, onError: { (error) -> Void in
print(error)
}).addDisposableTo(self.dispose)
我在视图模型中也有一个名为saveObject()
的函数。 如果我单击右侧导航栏,它将被发出。 并且会向createObservable
的观察者发送错误。
func saveObject(){
```````
```````
if condition {
createObservable.on(Event.Next(model))
createObservable.onCompleted()
}else{
createObservable.onError(MyError.someError)
}
}
问题是如果错误发生,createObservable将被关闭,所以我将来不会收到任何Next
事件。 我试图使用retry()
,但似乎会导致死锁,视图控制器无法再响应任何触摸事件。 那么有人可以告诉我如何解决这个问题吗? 非常感谢
viewModel!.createObservable.retry().subscribe(onNext: {[unowned self] (obj:PassbookModelType?) -> Void in
if let _ = obj{
self.dismissVC()
}
}, onError: { (error) -> Void in
print(error)
}).addDisposableTo(self.dispose)
我建议创建createObservable
类型的PublishSubject<Observable<PassbookModelType>>
,而不是使用BehaviorSubject<PassbookModelType?>
,我猜测,它意外地将两个Rx流在概念上相互分离: saveObject
进程本身(一次性进程)和重复启动用户操作启动的saveObject
进程。 我写了一个简短的例子来证明它。
let createObservable = PublishSubject<Observable<Int>>()
override func viewDidLoad() {
super.viewDidLoad()
createObservable.flatMap {
$0.map { obj in
print("success: \(obj)")
}
.catchError { err in
print("failure: \(err)")
return empty()
}
}.subscribe()
}
// Simulates an asynchronous proccess to succeed.
@IBAction func testSuccess(sender: UIView!) {
let oneShot = PublishSubject<Int>()
createObservable.onNext(oneShot)
callbackAfter3sec { res in
oneShot.onNext(1)
oneShot.onCompleted()
}
}
// Simulates an asynchronous process to fail.
@IBAction func testFailure(sender: UIView!) {
let oneShot = PublishSubject<Int>()
createObservable.onNext(oneShot)
callbackAfter3sec { res in
oneShot.onError(NSError(domain: "Error", code: 1, userInfo: nil))
}
}
func callbackAfter3sec(completion: Int -> ()) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(NSEC_PER_SEC * 3)), dispatch_get_main_queue()) {
completion(2)
}
}
有一个重要的优点:如果一次性进程将来会变成Rx样式(例如,像callbackAfter3sec() -> Observable<Int>
),则无需重新编写使用像上面的viewDidLoad
代码。 只有一个更改是将Observable<>
对象传递给createObservable.onNext(...)
。
抱歉我的英语能力差。 我希望这对你有意义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.