【问题标题】:RxJava retry based on logic基于逻辑的 RxJava 重试
【发布时间】:2015-08-30 15:14:44
【问题描述】:

在这种情况下,我有一个使用 Retrofit 的 API 调用,可能由于网络错误而失败。如果失败,我们将显示带有重试按钮的错误消息。当用户按下重试按钮时,我们需要再次重试最新的 Observable。

可能的解决方案:

  1. 重试:应该在订阅 observable 之前使用重试,如果发生错误,它将立即重新订阅,这是我不想要的,只有当用户按下重试按钮时,我才需要重新订阅。

  2. RetryWhen:它会在您发出项目时继续尝试,直到您发出 Observable 错误,然后它将停止。同样的问题,除非用户决定,否则我不需要启动重试过程。

  3. 重新订阅同一个 Observable:这个解决方案将开始发送 Observable 项目,问题在于我们使用了缓存操作符,所以如果一个 Observable 失败,我们会缓存失败的项目,当我们再次订阅时,我们又遇到了同样的错误。

还有其他解决方案吗?

【问题讨论】:

    标签: retrofit rx-java rx-android


    【解决方案1】:

    您可以使用 retryWhen,该参数 - Func1 - 返回一个指示何时应该重试的 Observable。例如:

    PublishSubject<Object> retryButtonClicked = PublishSubject.create();
    
    Observable
            .error(new RuntimeException())
            .doOnError(throwable -> System.out.println("error"))
            .retryWhen(observable -> observable.zipWith(retryButtonClicked, (o, o2) -> o))
            .subscribe();
    
    retryButtonClicked.onNext(new Object());
    

    每次 retryButtonClicked 发出一个事件,Observable 都会被重试

    这也是一个例子 - https://gist.github.com/benjchristensen/3363d420607f03307dd0

    【讨论】:

    • 根本没有重试,我认为 retryWhen 不能像你解释的那样工作,第一次 retyWhen 调用 zipWith 并且由于用户没有收到发出的项目没有点击按钮,它会放弃重试并吞下错误。
    • retryWhen 在错误发生时不被调用,它在 observable 创建时被调用一次,并且它返回一个指示何时重试的 Observable。我在上面发布的代码打印了两次“错误”。
    • 谢谢,您的解决方案是有效的,当我将它应用到我的代码中时,这是我的错误。您能否解释或指出任何有用的信息,说明为什么我不应该使用订阅者并使用 doONext , doOnError 代替?
    • 所以澄清一下。将retryWhen( 运算符与cache( 一起使用可以强制缓存破坏?
    • @krp 如果没有互联网,我想在用户单击重试按钮时重试连接。你的回答对我不起作用。我正在使用一个带有改造的可观察对象
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-18
    • 1970-01-01
    相关资源
    最近更新 更多