[英]rxswift error handle issue
I have a BehaviorSubject
named createObservable
in my view model. 我在视图模型中有一个名为
createObservable
的BehaviorSubject
。 And my view controller subscribe it. 我的视图控制器订阅它。
viewModel!.createObservable.subscribe(onNext: {[unowned self] (obj:PassbookModelType?) -> Void in
if let _ = obj{
self.dismissVC()
}
}, onError: { (error) -> Void in
print(error)
}).addDisposableTo(self.dispose)
I have a function named saveObject()
also in the view model. 我在视图模型中也有一个名为
saveObject()
的函数。 If I click the navigation bar right item it will be emitted. 如果我单击右侧导航栏,它将被发出。 And there is an error will send to
createObservable
's observer. 并且会向
createObservable
的观察者发送错误。
func saveObject(){
```````
```````
if condition {
createObservable.on(Event.Next(model))
createObservable.onCompleted()
}else{
createObservable.onError(MyError.someError)
}
}
The problem is that if the error happened the createObservable will be closed, so I won't receive any Next
event in the future. 问题是如果错误发生,createObservable将被关闭,所以我将来不会收到任何
Next
事件。 I tried to use retry()
, but it seems will cause deadlock, view controller can't response any touch event any more. 我试图使用
retry()
,但似乎会导致死锁,视图控制器无法再响应任何触摸事件。 So can some one tell me how to fix this issue? 那么有人可以告诉我如何解决这个问题吗? Thanks a lot
非常感谢
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)
I suggest to make the type of createObservable
PublishSubject<Observable<PassbookModelType>>
, instead of BehaviorSubject<PassbookModelType?>
which, I guess, accidentally flattens two Rx streams conceptually separatable each other: the saveObject
process itself (an one-shot process) and starting the saveObject
process initiated by user action repeatedly. 我建议创建
createObservable
类型的PublishSubject<Observable<PassbookModelType>>
,而不是使用BehaviorSubject<PassbookModelType?>
,我猜测,它意外地将两个Rx流在概念上相互分离: saveObject
进程本身(一次性进程)和重复启动用户操作启动的saveObject
进程。 I've written a short example to demonstrate it. 我写了一个简短的例子来证明它。
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)
}
}
There is an important merit with that: If the one-shot process would become in the Rx style (for example, like as callbackAfter3sec() -> Observable<Int>
) in the future, there were no need to re-write the use-side code like in the viewDidLoad
above. 有一个重要的优点:如果一次性进程将来会变成Rx样式(例如,像
callbackAfter3sec() -> Observable<Int>
),则无需重新编写使用像上面的viewDidLoad
代码。 There is an only one change to do is to pass an Observable<>
object to createObservable.onNext(...)
. 只有一个更改是将
Observable<>
对象传递给createObservable.onNext(...)
。
Sorry for my poor English skill. 抱歉我的英语能力差。 I hope this makes sense to you.
我希望这对你有意义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.