RxJava使用zip链接多个调用

时间:2016-11-18 11:53:41

标签: android rx-java

我正在尝试从一系列API调用中构造一个observable,但我无法让它工作。我所拥有的是使用ApiA返回Observables的四个API调用ApiBApiCApiDRxJavaCallAdapterFactory。必须首先调用ApiAApiB,然后在执行两者之后调用ApiC和ApiD。执行最后两个后,View被初始化。我正在使用zip操作员等待完成电话,我不确定是不是这样,但我对RxJava很新,所以如果有另一种更好的方法,请告诉我。 下面是我的代码,其中的评论显示了我遇到的问题

public Observable syncData() {
    return Observable.zip(
        // these two calls are executed
        callApiA(),
        callApiB(),
        (o, o2) -> Observable.zip(
            /* these two calls are not executed, it seems as if this zip has 
            no subscriber but i don't know why ... */
            callApiC(),
            callApiD(),
            (o, o2) -> {
                someLogic();
                return Observable.empty();
            }));
}

在视野中我只是习惯于这种方法

viewModel.syncData().subscribe(
            o -> mainAdapter.update(),
            throwable -> throwable.printStackTrace()
);

我再次对RxJava很新,所以任何帮助都会受到赞赏。感谢

2 个答案:

答案 0 :(得分:1)

你走在正确的轨道上。

但请注意,.zip最后一个参数Func未从Observable<R>函数返回call,而是直接R

所以你要将Observable归还Subscriber的{​​{1}},而不是它的事件。

需要

onNext

flatMap

这是伪代码,但我希望你明白这个想法:

  1. Observable.zip(callApi1(), callApi2(), Pair::new) .flatMap((pair) -> Observable.zip( Observable.just(pair.first()), Observable.just(pair.second()), callApiC(), callApiD(), (t1, t2, t3, t4) -> { someLogic() })); 前2个电话(A,B)
  2. 返回从这些函数返回的Zip个对象
  3. 使用Pair运算符(使用Pair运算符)
  4. 转换zip
  5. 使用接下来的2个电话(C,D)
  6. 撰写此flatMap
  7. Pair函数返回合成对象(记住,someLogic()应该返回someLogic而不是R
  8. 暗示未来: 首先尝试不使用lambda表达式编写它。然后您可以看到输入和输出参数,因此编写代码更容易。然后用lambda表达式重写它。

答案 1 :(得分:1)

重要的是Observable在订阅之前不会被执行。

因此,为了解释发生了什么,第一个Observable.zip被赋予了组合函数(callApiA(),callApiB()) -> Observable<Something>,因此它产生了Observable<Observable<Something>>。 observable作为元素发送,从未订阅过。

要修复它,您需要展平可观察流:Observable.zip(...).flatmap(s -> s)。这会将流展平为Observable<Something>并订阅内部可观察数据。