Skip to content

Instantly share code, notes, and snippets.

@Soamid
Last active October 26, 2019 14:40
Show Gist options
  • Save Soamid/e5567638cec63a4131ebac655c560977 to your computer and use it in GitHub Desktop.
Save Soamid/e5567638cec63a4131ebac655c560977 to your computer and use it in GitHub Desktop.
public Observable<Photo> searchForPhotos(String searchQuery) {
return Observable.fromCallable(() -> downloadUrlSource(searchQuery))
.flatMap(googleSiteSource -> Observable.fromArray(extractPhotoUrls(googleSiteSource).toArray(new String[0])))
.map(photoUrl -> {
try {
return getPhoto(photoUrl);
} catch (IOException e) {
log.log(Level.WARNING, "Could not download a photo", e);
}
return null; // ???!!!
});
}
public Observable<Photo> searchForPhotos(String searchQuery) {
return Observable.fromCallable(() -> downloadUrlSource(searchQuery))
.flatMap(googleSiteSource -> Observable.fromArray(extractPhotoUrls(googleSiteSource).toArray(new String[0])))
.flatMap(photoUrl -> {
try {
return Observable.just(getPhoto(photoUrl));
} catch (IOException e) {
log.log(Level.WARNING, "Could not download a photo", e);
}
return Observable.empty();
});
}
@Soamid
Copy link
Author

Soamid commented Oct 25, 2019

Przykład pokazuje, w jaki sposób radzić sobie z pomijaniem niektórych elementów w przypadku wystąpieniu błędu. Zależy nam na tym by błąd nie przerywał w tym przypadku strumienia więc wywołanie onError nie jest możliwe.

Pierwszy przykład (PhotoDownloaderBad) pokazuje intuicyjne, ale niestety nieprawidłowe podejście: w operatorze map opakowujemy problematyczne wywołanie w block try-catch. Jeśli wszystko poszło dobrze, zwracamy wartość.... ale co zwrócić jeśli wystąpił błąd? Zwrócenie null RX zasygnalizuje jako błąd. Można by zwracać jakąś atrapę obiektu i potem rozpoznawać ją w handlerze subskrypcji, ale to rozwiązanie też wydaje się niezgrabne i może prowadzić do błędów.

Zamiast tego warto zauważyć, że w RX każdą wartość możemy "wsadzić do pudełka", które potem będzie obsługiwane przez strumień. Użyjemy do tego operatora FlatMap, który specjalizuje się w rozpakowywaniu takich pudełek. Po zastosowaniu FlatMap (PhotoDownloaderGood) opakowujemy zwracany rezultat w Observable#just, a w przypadku błędu zwracamy Observable#empty, czyli "puste pudełko". W dół strumienia zostanie więc przepuszczona wartość lub nic, jeśli pudełko będzie puste.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment