我正在使用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解决方案很感兴趣。
答案 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);
输出是:
您可以根据自己的要求修改此示例。