改造2 + RxJava重试当

时间:2017-05-05 12:58:26

标签: android retrofit2 rx-java2

我正在使用Retrofit 2和RxJava 2适配器。

每当服务器返回401 Unauthorized时,我刷新令牌并重试请求:

apiCall.retryWhen(es -> es
    .flatMap(e -> {
        if (isUnauthorizedException(e)) {
            return refreshToken();
        }

        return Flowable.<User>error(e);
    }));

其中refreshToken是一个简单的改装调用:

public Flowable<User> refreshToken() {
    return retrofitService.login(userCredentials);
}

现在,我想限制这种刷新的次数。但是,简单地添加take(1)不起作用,因为然后重试在onNext之后立即收到onCompleted并在重试之前取消请求。

当然,我可以take(2)来达到预期的效果,但这似乎是一种黑客攻击。

使用Rx运算符实现它的最优雅方法是什么?还有一个带有“断言”逻辑的运算符(在平面图中摆脱if)?

另外我知道我可以使用OkHttp拦截器实现相同的功能,但我对Retrofit-RxJava解决方案很感兴趣。

1 个答案:

答案 0 :(得分:2)

文档中有一个很好的例子 重试3次,每次增加等待的秒数。

ObservableSource.create((Observer<? super String> s) -> {

  System.out.println("subscribing");
  s.onError(new RuntimeException("always fails"));

}).retryWhen(attempts -> {

  return attempts.zipWith(ObservableSource.range(1, 3), 
    (n, i) -> i).flatMap(i -> {

    System.out.println("delay retry by " + i + " second(s)");
    return ObservableSource.timer(i, TimeUnit.SECONDS);

  });
}).blockingForEach(System.out::println);

输出是:

  • 订阅
  • 延迟重试1秒
  • 订阅延迟重试2秒(
  • 订阅延迟重试3秒(
  • 订阅

您可以根据自己的要求修改此示例。