我是RxJava的新手,经常被flatMap函数搞糊涂了。根据{{3}},flatmap transform the items emitted by an Observable into Observables, then flatten the emissions from those into a single Observable
有人能为它提供一个好的用例吗?为什么将原始的Observable转换为Observables(复数),然后将它们转换为单个Observable。
为什么不用'地图'?
如果你在Android中给出一个很棒的例子,那么普通的Java就足够了。感谢
答案 0 :(得分:23)
我在您的问题上看到了标记Android
。所以,您可能应该熟悉Retrofit
。
让你的图像有两种方法:
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*/});
答案 1 :(得分:7)
假设你有一个
Observable<Foo> fooObservable;
并且您想要调用另一个方法,该方法需要Foo
并发出Observable<Bar>
类似的东西:
public Observable<Bar> getBars(Foo foo);
如果你这样做了:
fooObservable.map(foo -> getBars(foo));
您最终得到的是Observable<Observable<Bar>>
,因为您已经改变了Foo
- &gt; Observable<Bar>
这可能不是你想要的。
相反,您可以使用flatMap
“展开可观察的”:
Observable<Bar> barObservable = fooObservable.flatMap(foo -> getBars(foo));
答案 2 :(得分:2)
我经常使用它将一些UI事件转换为可观察的后台任务:
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
中的observable可以发出单个值,这在样本中完成。
这种方式我在声明中定义了UI和后台进程之间的交互。
我使用doOnError
处理错误,然后使用onErrorResumeNext(Observable.<Integer>empty())
来阻止observable终止onError
。因为我使用flatMap
,我的observable未完成(内部flatMap
是)并且正在等待下一次点击事件。
您可以在my article找到完整的代码示例。