rx-java2 - 我们如何在 retryWhen() 停止重试后获取 Throwable?

标签 rx-java2

  private String stringResult=null;
  private Throwable throwableResult=null;

  @Test
  public void whereIsTheThrowable() {
    Observable.just("foo")
      .map(this::justBlowUp)
      .retryWhen(errors -> errors.zipWith(Observable.range(1, 3), (n, i) -> i))
      .subscribe(s -> stringResult=s, throwable -> throwableResult=throwable);

    assertNull(stringResult);
    assertNotNull(throwableResult);
  }

  private String justBlowUp(String s) {
    throw new RuntimeException();
  }

该测试在 RxJava 2.1.7 中失败。 retryWhen()似乎消耗了 Throwable ,即使它不再重试。 subscribe() lambda 没有得到任何 Throwable .虽然这个测试很愚蠢(justBlowUp() 会爆炸),但您可以想象一个 Observable工作通常成功的链,只是偶尔失败,而且很少连续失败四次。但是,在那种情况下,拥有 Throwable 会很有用。用于记录目的。

retryUntil()允许 subscribe()得到最后的Throwable ... 但随后在 retryUntil()我们没有 Throwable根本无法对其做出决定(例如,如果它似乎是 Internet 连接错误,则重试 N 次,但对于其他一切都快速失败)。 retryWhen()似乎是更强大的选项,但我们如何获得最终的 Throwable , 在 retryWhen() 之后停止重试?

我可以使用一个字段来保存 Throwable , 设置在 retryWhen() 内逻辑,但感觉应该有一个更惯用的解决方案。

最佳答案

retryWhen 将处理程序的完成视为正常完成的指示器,因此,处理程序应该在重试选项用尽后失败:

Observable.just("foo")
.map(this::justBlowUp)
.retryWhen(errors -> errors.flatMap(new Function<Throwable, Observable<Integer>>() {
    int count;
    @Override
    public Observable<Integer> apply(Throwable error) {
        if (count++ < 3) {
            return Observable.just(count);
        }
        return Observable.error(error);
    }
}))
.test()
.assertFailure(RuntimeException.class);

关于rx-java2 - 我们如何在 retryWhen() 停止重试后获取 Throwable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49111878/

相关文章:

java - 如何使用 Mockito 在单元测试中模拟 ObservableTransformer

java - RxJava : Consume result of Observable on another thread

java - 关于 RxJava 和 PublishSubject 的初学者问题

android - RxJava 2.x - 由 PublishSubject 触发并与其他 Observable 合并的 Observable 获取 flatMap 不会被订阅/执行

java - 使用 RxJava2 正确处理背压和并发

exception - RxJava在空时发出错误

java - RxAndroid : How to emit zipped observable every minute?

java - RxJava 对列表执行操作并返回可观察对象

java - toBlockingFirst方法靠谱吗?

java - 如何在不重新订阅的情况下替换 Flowable