RX Java - 重试一些抛出异常的代码
RX Java - Retry some code that throws exception
我正在尝试使用 RX Java 来使用来自不断发送对象的源的一些数据。
我想知道如何为我自己的代码抛出异常的情况实施重试策略。例如,网络异常应该使用指数退避策略触发重试。
一些代码:
message.map(this::processMessage)
.subscribe((message)->{
//do something after mapping
});
processMessage(message)
是包含可能失败的风险代码的方法,它是我想重试的代码部分,但我不想阻止可观察对象使用来自源的数据。
对此有什么想法吗?
以文章为例:
http://kevinmarlow.me/better-networking-with-rxjava-and-retrofit-on-android/
他们有一天帮助了我。
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!")
);
未经测试,但 retryWhen 与 repeatWhen 不同,它不仅在 onComplete 中调用。
http://blog.danlew.net/2016/01/25/rxjavas-repeatwhen-and-retrywhen-explained/
-> 每个错误都是平面映射的,因此我们可以 return onNext(null)(触发重新订阅)或 onError(error)(避免重新订阅)。
退避政策:
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 在这种情况下比延迟更可取,因为它允许我们通过重试次数修改延迟。以上重试 3 次,每次重试延迟 5 ^ retryCount,只需少量运算符即可实现指数退避!
最近我开发了完全适合您需要的库。
如果将 Exponential
策略与 backupObservable
相结合,您将获得预期的结果。
我正在尝试使用 RX Java 来使用来自不断发送对象的源的一些数据。
我想知道如何为我自己的代码抛出异常的情况实施重试策略。例如,网络异常应该使用指数退避策略触发重试。
一些代码:
message.map(this::processMessage)
.subscribe((message)->{
//do something after mapping
});
processMessage(message)
是包含可能失败的风险代码的方法,它是我想重试的代码部分,但我不想阻止可观察对象使用来自源的数据。
对此有什么想法吗?
以文章为例:
http://kevinmarlow.me/better-networking-with-rxjava-and-retrofit-on-android/
他们有一天帮助了我。
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!")
);
未经测试,但 retryWhen 与 repeatWhen 不同,它不仅在 onComplete 中调用。
http://blog.danlew.net/2016/01/25/rxjavas-repeatwhen-and-retrywhen-explained/ -> 每个错误都是平面映射的,因此我们可以 return onNext(null)(触发重新订阅)或 onError(error)(避免重新订阅)。
退避政策:
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 在这种情况下比延迟更可取,因为它允许我们通过重试次数修改延迟。以上重试 3 次,每次重试延迟 5 ^ retryCount,只需少量运算符即可实现指数退避!
最近我开发了完全适合您需要的库。
如果将 Exponential
策略与 backupObservable
相结合,您将获得预期的结果。