RxSwift - onError 发出两次

Posted

技术标签:

【中文标题】RxSwift - onError 发出两次【英文标题】:RxSwift - onError emitted twice 【发布时间】: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)

以下是该观察者的职责

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

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

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

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

【问题讨论】:

【参考方案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()

以上是关于RxSwift - onError 发出两次的主要内容,如果未能解决你的问题,请参考以下文章

RxSwift:调用中的额外参数“onError”

RxSwift)订阅一个 observable 两次不工作

RxSwift - 执行控制流会导致异步操作被执行两次

RxSwift。结合最新。并不是所有的 observables 都发出了

Observable 只发出一个值?

RxSwift: 链 Completable 到 Observable