让我们假设我有流:
final Observable<Integer> integerObservable = Observable
.fromArray(1, 2, 3, 4, 5, 6)
.map(i -> {
if (i % 3 == 0) {
throw new RuntimeException("Haha");
} else {
return i;
}
}
);
如您所见,我可能会收到一些意外的异常。
如何实现跳过异常/错误并继续接收下一个元素的解决方案,以便我的目标订户能够在这种特殊情况下看到
1, 2, 4, 5
答案 0 :(得分:1)
您可以将“危险”代码移至“子”流,如果发生错误,则不返回任何元素:
Observable
.fromArray(1, 2, 3, 4, 5, 6)
.flatMap(ii -> Observable.just(ii).map(i -> {
if (i % 3 == 0) {
throw new RuntimeException("Haha");
} else {
return i;
}
}).onErrorResumeNext(Observable.empty())
)
.subscribe(System.out::println);
答案 1 :(得分:0)
没有像clazz
这样的东西。当源流发出错误时,表示流已终止,并且不会有任何其他事件。在此之后,将无法恢复或继续播放流。
如果应用程序设计正确,通常无需担心这种情况,因为对于您的问题有一个微不足道的解决方案:只需在错误到达下游之前对其进行处理。
.continueNextIfError
此外,您不能继续已终止的流,如果可观察的源是冷可观察的,则使用final Observable<Integer> integerObservable = Observable
.fromArray(1, 2, 3, 4, 5, 6)
.map(i -> {
try {
if (i % 3 == 0) {
throw new RuntimeException("Haha");
} else {
return i;
}
} catch (RuntimeException e) {
return -1;
}
)
.filter(i -> i >= 0);
// or flatMaps cases
final Observable<Integer> integerObservable = Observable
.fromArray(1, 2, 3, 4, 5, 6)
.flatMapSingle(i -> {
return Single.fromCallable(() -> {
if (i % 3 == 0) {
throw new RuntimeException("Haha");
} else {
return i;
}
})
.onErrorReturnItem(-1);
})
.filter(i -> i >= 0);
重新订阅可能会有所帮助。
答案 2 :(得分:0)
出于教育的原因,我找到了可以解决此问题的解决方案。
Drawer
以上代码的结果是(预期的):
Observable
.fromArray(1, 2, 3, 4, 5, 6)
.concatMapDelayError(i -> Observable.fromCallable(() -> {
if (i % 3 == 0) {
throw new RuntimeException("Haha");
} else {
return i;
}
}))
.onErrorResumeNext(Observable.empty())
.subscribe(
System.out::println,
throwable -> log.error("That escalated quickly", throwable));
无限流可能会有问题(值得检查)。