RxJava,flatmap的好用例

时间:2015-08-07 06:56:22

标签: android rx-java rx-android

我是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就足够了。感谢

3 个答案:

答案 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找到完整的代码示例。