首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >2+ RxJava retryWhen

2+ RxJava retryWhen
EN

Stack Overflow用户
提问于 2017-05-05 12:58:25
回答 1查看 2K关注 0票数 3

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

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

代码语言:javascript
复制
apiCall.retryWhen(es -> es
    .flatMap(e -> {
        if (isUnauthorizedException(e)) {
            return refreshToken();
        }

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

其中refreshToken是一个简单的更新调用:

代码语言:javascript
复制
public Flowable<User> refreshToken() {
    return retrofitService.login(userCredentials);
}

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

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

使用Rx操作符来实现它的最优雅的方法是什么?还有一个带有“断言”逻辑的操作符(以消除平面映射中的if )吗?

此外,我知道我可以使用OkHttp拦截器实现同样的目标,但我对RxJava解决方案很感兴趣。

EN

回答 1

Stack Overflow用户

发布于 2017-10-26 01:19:21

文档中有一个很好的例子。

这个重试3次,每次增加它等待的秒数。

代码语言:javascript
复制
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秒
  • 订阅

您可以根据需要修改此示例。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43805616

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档