RxJava重试N次

时间:2017-05-09 17:35:19

标签: rx-java

RxJava 2

我试图在rxJava中进行非常简单的重试,这将重试3次然后导致原始错误。这就是我现在所拥有的:

public void retry3() {
    Observable<Object> retry = Observable
         .error(new IllegalStateException())
         .retryWhen(errors -> errors
             .zipWith(Observable.range(1, 3), (n, i) -> {
                  System.out.println("Retry: " + i);
                  return i;
             }));

    System.out.println("start");
    retry.blockingFirst();
    System.out.println("stop");
}

但执行上述操作会导致:

start
Retry: 1
Retry: 2
Retry: 3

然后执行似乎永远阻止。所以有两个问题:

  • 如何使这项工作?
  • 为什么它不能正常工作,我应该如何调试呢?

2 个答案:

答案 0 :(得分:0)

来自blockingFirst() docs:

  

返回此Observable或throws发出的第一个项目   如果它没有发出任何项目,则为NoSuchElementException。

在你的情况下,Observable工作得很好,但它会抛出NoSuchElementException,因为最终没有项目被发出。您重试3次,然后Observable结束 - 发送onComplete()

  

如何使这项工作?

您可以使用blockingSubscribe(),然后您的案例将按预期运作。

  

为什么它不能像它一样工作,我应该如何调试它?

在这种情况下,您应该观察异常以了解发生了错误,您可以使用doOnXXX()运算符在各种通知中添加打印,以观察错误并且无法按预期工作。

答案 1 :(得分:0)

如果我理解正确,你希望最终结果是第一个错误,所以你需要以某种方式跟踪它。一个有效的解决方案是:

public void retry3() {
    // this is just some preparation so we can see the result and understand it better.
    // Basically, this is an Observable that will:
    // - fail with different exceptions
    // - show us what those are
    final Random random = new Random();
    final Observable<Object> errorReturningObservable = Observable
            .just(0)
            .flatMap(i -> Observable.error(new Exception("Exception " + random.nextInt())))
            .doOnError(error -> System.out.println("Emitted " + error.getMessage()));

    // Here is the actual retry logic:
    // - If there's an error, resume by doing the retry
    // - If at the end of the retries, there's still an error, return the original one
    final Observable<Object> retryingObservable = errorReturningObservable
            .onErrorResumeNext(error -> errorReturningObservable
                    .retry(2)
                    .onErrorResumeNext(Observable.error(error))
    );

    System.out.println("start");
    retryingObservable
            .subscribe(
                    result -> System.out.println("Won't get here!"),
                    error -> System.out.println("The final error is: " + error.getMessage())
            );
    System.out.println("stop");
}

如果你运行它,你应该看到类似的东西:

start
Emitted Exception 2138850329 << first emitted error
Emitted Exception 1806115610
Emitted Exception -40768559
Emitted Exception 871227422
The final error is: Exception 2138850329 << matches the one returned at the end
stop