【问题标题】:rxswift error handle issuerxswift 错误处理问题
【发布时间】:2016-02-26 09:20:59
【问题描述】:

我的视图模型中有一个名为 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)

【问题讨论】:

    标签: swift rx-swift


    【解决方案1】:

    我建议使用 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)
        }
    }
    

    这样做有一个重要的优点:如果 one-shot 过程将来成为 Rx 风格(例如,像callbackAfter3sec() -&gt; Observable&lt;Int&gt;),则无需重新编写使用端代码就像上面的viewDidLoad 一样。唯一要做的更改是将Observable&lt;&gt; 对象传递给createObservable.onNext(...)。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-12
      • 2014-07-31
      • 2019-03-17
      • 2010-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多