Cara saya berpikir tentang hal itu adalah bahwa Anda menggunakan flatMap
ketika fungsi yang Anda ingin masukkan map()
kembali Observable
. Dalam hal ini Anda mungkin masih mencoba menggunakan map()
tetapi itu tidak praktis. Biarkan saya mencoba menjelaskan mengapa.
Jika dalam kasus seperti itu Anda memutuskan untuk tetap dengan map
, Anda akan mendapatkan Observable<Observable<Something>>
. Misalnya dalam kasus Anda, jika kami menggunakan pustaka RxGson imajiner, yang mengembalikan metode Observable<String>
dari itu toJson()
(bukan hanya mengembalikan a String
) itu akan terlihat seperti ini:
Observable.from(jsonFile).map(new Func1<File, Observable<String>>() {
@Override public Observable<String>> call(File file) {
return new RxGson().toJson(new FileReader(file), Object.class);
}
}); // you get Observable<Observable<String>> here
Pada titik ini akan sangat sulit untuk subscribe()
diamati. Di dalamnya Anda akan mendapatkan Observable<String>
yang Anda butuhkan lagi subscribe()
untuk mendapatkan nilai. Yang tidak praktis atau enak dilihat.
Jadi untuk membuatnya berguna satu ide adalah untuk "meratakan" ini dapat diamati dari diamati (Anda mungkin mulai melihat dari mana nama _flat_Map berasal). RxJava menyediakan beberapa cara untuk meratakan yang dapat diamati dan demi kesederhanaan mari kita asumsikan penggabungan adalah apa yang kita inginkan. Penggabungan pada dasarnya mengambil banyak yang bisa diobservasi dan memancarkan setiap kali salah satu dari mereka memancarkan. (Banyak orang akan berpendapat bahwa beralih akan menjadi default yang lebih baik. Tetapi jika Anda hanya memancarkan satu nilai, itu tidak masalah.)
Jadi ubah cuplikan kami sebelumnya yang akan kami dapatkan:
Observable.from(jsonFile).map(new Func1<File, Observable<String>>() {
@Override public Observable<String>> call(File file) {
return new RxGson().toJson(new FileReader(file), Object.class);
}
}).merge(); // you get Observable<String> here
Ini jauh lebih bermanfaat, karena dengan berlangganan (atau memetakan, atau memfilter, atau ...) Anda baru saja mendapatkan String
nilainya. (Juga, ingatlah Anda, varian semacam merge()
itu tidak ada di RxJava, tetapi jika Anda memahami gagasan penggabungan maka saya harap Anda juga memahami cara kerjanya.)
Jadi pada dasarnya karena itu merge()
mungkin hanya akan berguna ketika berhasil map()
mengembalikan yang dapat diamati dan jadi Anda tidak perlu mengetik ini berulang-ulang, flatMap()
diciptakan sebagai steno. Ini menerapkan fungsi pemetaan seperti biasa map()
, tetapi kemudian bukannya memancarkan nilai yang dikembalikan itu juga "meratakan" (atau menggabungkan) mereka.
Itu kasus penggunaan umum. Ini sangat berguna dalam basis kode yang menggunakan Rx allover tempat dan Anda punya banyak metode mengembalikan yang dapat diamati, yang Anda ingin rantai dengan metode lain yang mengembalikan diamati.
Dalam use case Anda, itu kebetulan juga berguna, karena map()
hanya dapat mengubah satu nilai yang dipancarkan onNext()
menjadi nilai lain yang dipancarkan onNext()
. Tapi itu tidak bisa mengubahnya menjadi beberapa nilai, tidak ada nilai sama sekali atau kesalahan. Dan seperti yang ditulis akarnokd dalam jawabannya (dan pikiran Anda dia jauh lebih pintar dari saya, mungkin secara umum, tetapi setidaknya ketika datang ke RxJava) Anda tidak harus membuang pengecualian dari Anda map()
. Jadi, alih-alih, Anda dapat menggunakan flatMap()
dan
return Observable.just(value);
ketika semuanya berjalan dengan baik, tapi
return Observable.error(exception);
ketika sesuatu gagal.
Lihat jawabannya untuk cuplikan lengkap: https://stackoverflow.com/a/30330772/1402641
subscriber.onError()
dll. Semua contoh yang saya lihat memiliki kesalahan yang dialihkan seperti itu. Apakah itu tidak masalah?