Я думаю о том, что вы используете, 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()
и т. Д. Все примеры, которые я видел, направляли ошибки таким образом. Это не имеет значения?