Як я думаю про це, це те, що ви використовуєте, flatMap
коли функція, яку ви хотіли поставити всередину, map()
повертає Observable
. У такому випадку ви все ще можете спробувати використовувати, map()
але це було б непрактично. Дозвольте спробувати пояснити, чому.
Якби в такому випадку ви вирішили дотримуватися map
, ви отримаєте Observable<Observable<Something>>
. Наприклад, у вашому випадку, якби ми використовували уявну бібліотеку RxGson, яка повертала метод Observable<String>
із свого toJson()
методу (замість простого повернення a String
), це виглядатиме так:
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
На цьому етапі subscribe()
до такого спостережуваного було б досить складно . Всередині нього ви отримаєте те, Observable<String>
до чого вам знову знадобиться subscribe()
отримати цінність. Що не практично чи приємно дивитись.
Отже, щоб зробити корисною однією ідеєю є "сплющити" це спостережуване спостереження (ви можете почати бачити, звідки походить ім'я _flat_Map). RxJava пропонує декілька способів згладити спостережувані, а для простоти дозволяємо припускати злиття - це те, що ми хочемо. Об'єднання в основному займає купу спостережуваних даних і видає всякий раз, коли хтось із них випускає. (Багато людей стверджують, що перемикання стане кращим за замовчуванням. Але якщо ви випромінюєте лише одне значення, це все одно не має значення.)
Таким чином, змінивши наш попередній фрагмент, ми отримаємо:
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
Це набагато корисніше, тому що підписуючись на це (або зіставляючи, або фільтруючи, або ...), ви просто отримуєте String
значення. (Також, зауважте, такого варіанту merge()
існування в RxJava не існує, але якщо ви розумієте ідею злиття, то, я сподіваюся, ви також зрозумієте, як це буде працювати.)
Тому в основному тому, що таке, merge()
ймовірно, може бути корисним лише тоді, коли йому вдасться map()
повернути спостережуване, і тому вам не доведеться вводити це знову і знову, flatMap()
було створено як скорочення. Він застосовує функцію відображення так само, як звичайно map()
, але пізніше замість випромінювання повернених значень також "згладжує" (або об'єднує) їх.
Це загальний випадок використання. Найбільш корисно в кодовій базі, яка використовує Rx-розподільник місця, і у вас є багато методів повернення спостережуваних даних, які ви хочете пов'язати з іншими методами повернення спостережних даних.
У вашому випадку це буває і корисним, оскільки map()
може трансформувати лише одне значення, випущене в onNext()
інше, випущене в onNext()
. Але він не може перетворити його на кілька значень, взагалі немає значення або помилки. І як писав у своїй відповіді akarnokd (і зауважте, він набагато розумніший за мене, напевно, загалом, але принаймні, якщо мова йде про RxJava), ви не повинні кидати винятки зі свого map()
. Тож замість цього можна використовувати flatMap()
і
return Observable.just(value);
коли все йде добре, але
return Observable.error(exception);
коли щось не вдається.
Дивіться його відповідь на повний фрагмент: https://stackoverflow.com/a/30330772/1402641
subscriber.onError()
і т. Д. Усі приклади, які я бачив, таким чином направляли помилки. Це не має значення?