【问题标题】:RxSwift - onError emitted twiceRxSwift - onError 发出两次
【发布时间】:2018-10-06 20:48:39
【问题描述】:

我一直在尝试使用 RxSwift,我正在寻求有关如何正确处理观察者的帮助。我有一个观察者正在观察 Publish Subject

authPublisherSubject.asObserver()

        .subscribe(onNext: { (status) in

        }, onError: { [unowned self] (error) in

        }, onCompleted: { [unowned self] in

  }).disposed(by: disposeBag)

以下是该观察者的职责

  1. 显示活动指示器
  2. 隐藏活动指示器
  3. 显示错误(如果有)
  4. 登录成功后继续

每次用户点击登录按钮时,我都会订阅这个观察者。方法是否正确?

如果我收到错误,下次我订阅此观察者时,即下一次用户点击登录时,由于某种原因,旧错误将被保留,并且 onError 会与旧错误一起自动发出。 但是,据我了解,Publisher Subject 只会发出观察后发生的那些事件。

我无法理解这里发生了什么。

【问题讨论】:

    标签: ios swift reactive-programming rx-swift


    【解决方案1】:

    这里似乎存在一些误解。

    首先,您不是订阅Observer,而是订阅Observable。 Observable 是可以观察到的东西,观察者进行观察。对我来说,更好的思考方式是 Observable 产生值,而 Observer 消耗它们。所以你 subscribeObservables。您的示例代码有效,因为 asObserver() 函数只返回 self。真可惜。

    其次,Rx 是一种声明式的编程方法,而不是命令式的。这意味着您只需设置一次 Rx 链,而不是“每次点击按钮时”。在视图控制器的 viewDidLoad 中设置一次订阅。现在,按钮点击不会发出错误事件,因此链中肯定有您没有提到的东西出错了。

    正如您在评论中提到的,如果发出错误,它将破坏可观察链。有几种方法可以处理这个问题。第一个也是最明显的是确保链中的任何内容都不会发出错误。另一种方法是将可能出错的运算符包装在 flatMap 中,然后使用 materialize()catchError within flatMap。阻止错误转义 flatMap 很重要,因为如果发生这种情况,它将破坏主链。

    【讨论】:

      【解决方案2】:

      每次用户点击登录按钮时,我都会订阅这个观察者。方法正确吗?

      • 不,只需要订阅一次。在每次登录时单击它一次又一次地订阅,因此您收到了两次消息。为此,您必须在 viewWillAppear 方法中添加订阅。试试这个希望它有效。

      【讨论】:

      • 感谢您的回复。如果我在 onError 的情况下只订阅一次,观察者就会被处理掉。这意味着我不会收到任何后续事件的回电。我应该如何处理这种情况?
      • 防止 observables 因为错误事件而被释放。您可以使用 catchError 系列来做到这一点。
      • .catchError { err in print("failure: (err)") return empty() }
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-03
      • 1970-01-01
      • 1970-01-01
      • 2016-08-01
      相关资源
      最近更新 更多