rxswift 错误处理问题 [英] rxswift error handle issue

查看:42
本文介绍了rxswift 错误处理问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的视图模型中有一个名为 createObservableBehaviorSubject.我的视图控制器订阅它.

I have a BehaviorSubject named createObservable in my view model. 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)

我在视图模型中有一个名为 saveObject() 的函数.如果我单击导航栏右侧的项目,它将被发出.并且有一个错误会发送给 createObservable 的观察者.

I have a function named saveObject() also in the view model. If I click the navigation bar right item it will be emitted. And there is an error will send to createObservable's observer.

func saveObject(){
     ```````
     ```````
    if condition {
        createObservable.on(Event.Next(model))
        createObservable.onCompleted()
    }else{
       createObservable.onError(MyError.someError)
    }
}

问题是,如果发生错误,createObservable 将被关闭,因此我将来不会收到任何 Next 事件.我尝试使用 retry(),但它似乎会导致死锁,视图控制器无法再响应任何触摸事件.那么有人可以告诉我如何解决这个问题吗?非常感谢

The problem is that if the error happened the createObservable will be closed, so I won't receive any Next event in the future. I tried to use retry(), but it seems will cause deadlock, view controller can't response any touch event any more. 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)

推荐答案

我建议将类型设为 createObservable PublishSubject>,而不是BehaviorSubject<PassbookModelType?>,我猜,它意外地将两个概念上彼此分离的 Rx 流压平了:saveObject 过程本身(一个一次性过程)并启动 saveObject 过程由用户反复启动.我写了一个简短的例子来演示它.

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. 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)
    }
}

这有一个重要的优点:如果一次性过程将成为 Rx 风格(例如,像 callbackAfter3sec() -> Observable),无需像上面的 viewDidLoad 那样重写使用端代码.唯一要做的更改是将 Observable<> 对象传递给 createObservable.onNext(...).

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. There is an only one change to do is to pass an Observable<> object to createObservable.onNext(...).

对不起,我的英语水平很差.我希望这对您有意义.

Sorry for my poor English skill. I hope this makes sense to you.

这篇关于rxswift 错误处理问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆