我正在尝试使用RX Java来消耗来自持续发送对象的源的一些数据。
我想知道如何为我自己的代码抛出异常的情况实现重试策略。例如,网络异常应该使用指数退避策略触发重试。
一些代码:
Trimester I
ABC
Trimester II
CDF
Trimester III
FGH
Trimester IV
XYZ
Trimester I
PQR
FGH
Trimester II
MNO
message.map(this::processMessage)
.subscribe((message)->{
//do something after mapping
});
是包含可能失败的风险代码的方法,以及我想要重试的代码部分,但我不想阻止observable从源代码中消耗数据。
对此有何想法?
答案 0 :(得分:2)
message
.map(this::processMessage)
.retryWhen(errors -> errors.flatMap(error -> {
if (error instanceof IOException) {
return Observable.just(null);
}
// For anything else, don't retry
return Observable.error(error);
})
subscribe(
System.out::println,
error -> System.out.println("Error!")
);
或捕获错误
message.map(this::processMessage)
.onErrorReturn(error -> "Empty result")
.subscribe((message)->{})
或发出错误
message
.map(this::processMessage)
.doOnError(throwable -> Log.e(TAG, "Throwable " + throwable.getMessage()))
.subscribe(
System.out::println,
error -> System.out.println("Error!")
);
未经测试,但重试时不同于重复时不仅在onComplete中调用。
http://blog.danlew.net/2016/01/25/rxjavas-repeatwhen-and-retrywhen-explained/ - >每个错误都是flatmapped,以便我们可以返回onNext(null)(触发重新订阅)或onError(错误)(以避免重新订阅)。
退避政策:
source.retryWhen(errors ->
errors
.zipWith(Observable.range(1, 3), (n, i) -> i)
.flatMap(retryCount -> Observable.timer((long) Math.pow(5, retryCount), TimeUnit.SECONDS))
);
在这种情况下,flatMap + timer优于延迟,因为它允许我们通过重试次数来修改延迟。以上重试三次,并将每次重试延迟5 ^ retryCount,只需少量操作符即可实现指数退避!
答案 1 :(得分:1)
答案 2 :(得分:0)