使用 Fallback Observable x 次

Use Fallback Observable x number of times

我有一个 Observable,它在 onErrorResumeNext 方法中实现了错误处理。

getMyObservable(params)
                .take(1)
                .doOnError(e -> {
                })
                .onErrorResumeNext(throwable -> {
                    if (throwable.getMessage().contains("401")) {
                        return getMyObservable(params);
                    } else {
                        sendServerCommunicationError();
                        return Observable.error(throwable);
                    }
                })
                .subscribe(result -> {
                             ...                                }
                });

GetMyObservable() returns 来自生成的客户端的 Web 服务请求。用例是:如果我们收到 401,我们可能需要使用新的 UserToken 刷新客户端。这就是为什么我们在 onErrorResumeNext() 中使用 Fallback Observable 而不能只使用重试。

我有一些问题:

  1. 为什么我需要实现 doOnError?如果我不实现它,我有时会得到一个 "onError not implemented" 异常。我想当我使用 onErrorResumeNext 时,这个方法会在发生错误时自动使用。
  2. 我如何在特定错误(如 401)上实现这一点?我使用具有一些退避时间的回退 Observable,5 次后我产生错误。那么我可以以某种方式结合 retryWhen 和 onErrorResumeNext 还是以不同的方式完成?

Why do I need to implement doOnError?

你不需要,doOnError 不是错误处理程序,而是错误通道的一瞥。您必须在 subscribe:

中实施错误处理程序
.subscribe(result -> {
    // ...
},
error -> {
    // ...
});

How can I achieve that on specific Errors (like 401) I use a fallback Observable with some backoff time and after 5 Times

使用retryWhen:

Observable.defer(() -> getMyObservable(params))
.retryWhen(errors -> {
    AtomicInteger count = new AtomicInteger();
    return errors.flatMap(error -> {
       if (error.toString().contains("401")) {
           int c = count.incrementAndGet();
           if (c <= 5) {
               return Observable.timer(c, TimeUnit.SECONDS);
           }
           return Observable.error(new Exception("Failed after 5 retries"));
       }
       return Observable.error(error);
    })
})