Wenn ich ein Observalbe haben:RxJava Observable und Abonnent für das Überspringen von Ausnahmen?
List<Integer> ints = Lists.newArrayList(1, 2, 0, 3, 4);
Observable<Integer> o1 = Observable.from(ints);
Ich möchte eine andere beobachtbar erzeugen, die Kluft von 12:
Observable<Integer> o2 = o1.map(i -> 12/i);
o2.subscribe(
v -> logger.info ("Subscriber value {}", v) ,
t -> logger.error("Subscriber onError {} : {}", t.getClass() , t.getMessage())
);
Es ist offensichtlich, es eine Fehlermeldung anzeigt, und gestoppt, wenn sie begegnen ‚0‘:
RxTest - Subscriber value 12
RxTest - Subscriber value 6
RxTest - Subscriber onError class java.lang.ArithmeticException :/by zero
Aber was, wenn ich möchte, dass der Observer (o2) die Ausnahme auslässt?
Ich sehe in RxJava Doc über error handling, gibt es keine Möglichkeit, den Fehler zu überspringen. Die onErrorResumeNext()
und onExceptionResumeNext()
benötigt eine Backup/FallbackObservable
, die nicht was ich will. Der onErrorReturn
muss den Rückgabewert angeben.
Alle drei Fehlerbehandlungsmethoden können den ursprünglichen Beobachter nicht fortsetzen. zum Beispiel:
Observable<Integer> o2 = o1.map(i -> 12/i)
.onErrorReturn(t -> 0);
Er druckt:
RxTest - Subscriber value 12
RxTest - Subscriber value 6
RxTest - Subscriber value 0
Nicht
die einzige Lösung, um den Rest 12/3 und 12/4 Druck scheint in der map
Funktion Relais:
Observable<Integer> o2 = o1.map(i -> {
try {
return Optional.of(12/i);
} catch (ArithmeticException e) {
return Optional.empty();
}
}).filter(Optional::isPresent)
.map(o -> (Integer) o.get());
Es funktioniert, aber es ist umständlich. Ich frage mich, ob es eine Möglichkeit ist leicht jeden RuntimeException
zu überspringen, wenn die Manipulation Observable
(wie map
)
Die oben über Ausnahme in Observable
Skipping ist. Im Folgenden geht es um das Überspringen Ausnahme in der Subscriber
:
Die Situation ist die gleiche:
List<Integer> ints = Lists.newArrayList(1, 2, 0 , 3 , 4);
Observable<Integer> o1 = Observable.from(ints);
o1.subscribe(
i -> logger.info("12/{} = {}", i, 12/i),
t -> logger.error("{} : {}", t.getClass() , t.getMessage()),
() -> logger.info("onCompleted")
);
Es druckt:
Wenn Ausnahme in onNext
auftritt, löst es onError
und NOT REAKTION auf Daten von Observable
. Wenn ich möchte, dass der Abonnent die Ausnahme verschluckt, muss ich versuchen, die ArithmeticException
in der onNext()
zu fangen. Gibt es eine sauberere Lösung?
Es scheint, wenn ein Subscriber
mit einem Fehler in der onNext()
konfrontiert ist, die innerhalb (onNext
) nicht behandelt werden kann, soll es aufhören, oder? Ist es ein gutes Design?
So wie ich es betrachten, 'OnNext()' entspricht 'Iterator.next()' - und wenn ein Problem eine Sammlung gibt es Iterieren - eine Ausnahme ausgelöst wird und der Iterator zieht mit (es doesn 't "resume" iterating) - siehe zB [ConcurrentModificationException] (http://docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificationException.html). Das ist die gleiche Art von Verhalten, die wir hier haben. Das heißt, @benjchristensen könnte mehr Licht auf das Thema werfen. – alfasin
Das 'Optional'-Mapping ist wahrscheinlich meine bevorzugte Art, dies zu handhaben. Es ist ziemlich klar, und der Filter isst Ereignisse schön. Es ist eine ziemlich gute Möglichkeit, es zu kapseln. Ich hätte in Scala einen "Try" -Typ verwendet und danach gefiltert. – BeepDog