首页 > 解决方案 > 使用 Fallback Observable x 次

问题描述

我有一个 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() 从生成的客户端返回 Web 服务请求。用例是:如果我们收到 401,我们可能需要使用新的 UserToken 刷新客户端。这就是为什么我们在 onErrorResumeNext() 中使用 Fallback Observable 而不能只使用重试。

我有一些疑问:

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

标签: javaandroidrx-javareactive-programmingrx-android

解决方案


为什么我需要实现doOnError?

您没有也不doOnError是错误处理程序,而是窥视错误通道。您必须在以下位置实现错误处理程序subscribe

.subscribe(result -> {
    // ...
},
error -> {
    // ...
});

如何在特定错误(如 401)上实现这一点

使用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);
    })
})

推荐阅读