RxJava, хороший пример использования flatmap
Я новичок в RxJava, часто путаюсь в функции flatMap. Согласно doc, flatmap transform the items emitted by an Observable into Observables, then flatten the emissions from those into a single Observable
Может ли кто - нибудь привести хороший пример его использования? Зачем превращать исходное наблюдаемое в наблюдаемое (множественное число), а затем превращать их в единое наблюдаемое?
Почему бы вам просто не использовать "карту"?
Если вы приведете пример в Android, это потрясающе, в противном случае достаточно простой Java. Спасибо
3 ответов:
Допустим, у вас есть
Observable<Foo> fooObservable;И вы хотите вызвать другой метод, который принимает
Fooи выдаетObservable<Bar>Что-то вроде:
public Observable<Bar> getBars(Foo foo);Если вы это сделали:
fooObservable.map(foo -> getBars(foo));Вы закончите с
Observable<Observable<Bar>>, потому что вы трансформировали свойFoo->Observable<Bar>а это, вероятно, не то, чего ты хочешь.Вместо этого вы можете использовать
flatMap, который "сглаживает наблюдаемое":Observable<Bar> barObservable = fooObservable.flatMap(foo -> getBars(foo));
Я вижу тег
Androidна вашем вопросе. Так что, вероятно, вы должны быть знакомы сRetrofit.Давайте представим, что у вас есть 2 метода:
public interface FoxreyRestApi { @POST("/signin") Observable<SignInResponse> signin(@Body SignInRequest request); @GET("/user") Observable<User> getUser(String accessToken); }Вы хотите получить пользовательские данные, но вам нужно
accessToken, которое возвращаетSignInResponse.Вы можете сделать это:
1). Создайте свой
RestAdapter.2). Выполняйте запросы один за другим:
restAdapter.signin(request) .flatMap(r -> restAdapter.getUser(r.getAccessToken())) .subscribe(user -> {/*User your user*/});
Очень часто я использую его для преобразования некоторых событий пользовательского интерфейса в наблюдаемые фоновые задачи:
ViewObservable.clicks(calculateBtn) .flatMap(new Func1<OnClickEvent, Observable<Integer>>() { @Override public Observable<Integer> call(OnClickEvent onClickEvent) { return observeBackgroundOperation() .observeOn(AndroidSchedulers.mainThread())//interaction with UI must be performed on main thread .doOnError(new Action1<Throwable>() {//handle error before it will be suppressed @Override public void call(Throwable throwable) { progress.setVisibility(View.GONE); calculateBtn.setEnabled(true); Toast.makeText(IOCombineSampleActivity.this, R.string.mix_error_message, Toast.LENGTH_SHORT).show(); } }) .onErrorResumeNext(Observable.<Integer>empty());//prevent observable from breaking } }) .subscribe(new Action1<Integer>() {...});Поскольку легко определить фоновые операции с помощью observable, я использовал
Заметим, что наблюдаемое вflatMap, чтобы преобразовать события нажатия кнопки в "что-то сделанное в фоновых событиях" (например, сетевой запрос, завершенный с помощью Retrofit), а затем наблюдать за ними.flatMapможет выдавать единичное значение, что и делается в выборке.Таким образом, я декларативно определил взаимодействие между пользовательским интерфейсом и фоновыми процессами. Я обрабатываю ошибки с помощью
Полный образец кода Вы можете найти в моей статье.doOnError, а затем используюonErrorResumeNext(Observable.<Integer>empty()), чтобы предотвратить завершение observable с помощьюonError. Поскольку я используюflatMap, мой observable не завершен (в то время как внутреннийflatMapбыл) и ждет событий следующего щелчка.
Comments