【问题标题】:RxAndroid Re-Subscribe to Observable onError and onCompleteRxAndroid 重新订阅 Observable onError 和 onComplete
【发布时间】:2017-10-03 18:35:45
【问题描述】:

我的问题可能更多是概念性的。
我通过Observable 合同得知,在调用onCompleteonError 之后,我的Observable 将不再发出任何项目。
但我使用的是 Android 的 RxBindings,因此它不是“我的Observable”,而是点击发出项目的Button

fun observeForgotPasswordButton(): Disposable {
    return view.observeForgotPasswordButton()
            .flatMap {
                authService.forgotPassword(email).toObservable<Any>()
            }
            .subscribe({
                // on next
                Timber.d("fun: onNext:")
            }, { error ->
                // on error
                Timber.e(error, "fun: onError")
            }, {
                // onComplete
                Timber.d("fun: onComplete")
            })
}

observeForgotPasswordButton() 返回一个Observable

fun observeForgotPasswordButton(): Observable<Any> = RxView.clicks(b_forgot_password)

问题是authService.forgotPassword(email)Completable,它会调用onCompleteonError,这两者都导致我无法再重复使用该按钮,因为订阅结束了。
有没有办法规避这种行为? 因为在发生错误时我希望能够重试。
此外,我希望可以发送多个忘记密码的电子邮件。

【问题讨论】:

  • 过早取消订阅上述内容的唯一方法是发生错误。如果 forgotPassword 总是成功,我认为不会调用 onComplete 。检查 rxJava error handling operators。你也可以使用flatMapCompletable
  • 我做了更多的挖掘,发现了一个pretty solid explanation of error handling in rx。正如博客文章所描述的那样,我犯了一个新手错误,即在authService 中抛出异常,而不是在错误状态下调用onNext。这是 rx 方式...
  • @grAPPfruit 使用 onError 而不是对错误状态建模并不是真正的rookie 错误。甚至 Square 的 Retrofit 也做过一次。
  • @PhoenixWang 成就了我的一天 ;)

标签: android rx-java observable rx-android


【解决方案1】:

您可以使用retry()repeat() 运算符自动重新订阅原始Observable(或Completable)。

fun observeForgotPasswordButton(): Disposable {
    return view.observeForgotPasswordButton()
            .flatMap {
                authService.forgotPassword(email).toObservable<Any>()
            }
            .repeat() // automatically resubscribe on completion
            .retry()  // automatically resubscribe on error
            .subscribe({
                // on next
                Timber.d("fun: onNext:")
            }, { error ->
                // on error
                Timber.e(error, "fun: onError")
            }, {
                // onComplete
                Timber.d("fun: onComplete")
            })
}

【讨论】:

  • 随着重复,observable 将无限期地激发所有最初发出的值。这意味着每个初始用户输入。我不认为这是他想要的。在这种情况下,如果你想保持 observable 活着,你只需要处理错误。
  • masp 是对的,这不是我想要的。另外我认为您的回答是错误的,但我不是这方面的专家,所以我就这样吧……@masp,您所说的“处理错误”是什么意思?我创建了一个测试项目,其中我的Observable.interval(1, TimeUnit.SECONDS) 是我的Observable 源。我用.flatMapCompletable(__ -&gt; Completable.complete()) 链接它,然后用CompletableObserver 订阅,我只打印方法名称。我看到的只是onSubscribe。从来没有其他...我不明白。
  • 看我对这个问题的评论...问题有解决办法
  • @grAPPfruit 诸如Observable.interval 之类的可观察对象永远不会完成,除非出现错误或被处理掉。所以,你永远不应该收到onComplete。此外,如果您使用Completable 作为链的最后一部分,您也将永远不会收到任何onNext 事件。至于测试部分,您分享的博客也对我有帮助。尤其是关于被屏蔽异常的部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多