我正在尝试从一系列API调用中构造一个observable,但我无法让它工作。我所拥有的是使用ApiA
返回Observables的四个API调用ApiB
,ApiC
,ApiD
和RxJavaCallAdapterFactory
。必须首先调用ApiA
和ApiB
,然后在执行两者之后调用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很新,所以任何帮助都会受到赞赏。感谢
答案 0 :(得分:1)
你走在正确的轨道上。
但请注意,.zip
最后一个参数Func
未从Observable<R>
函数返回call
,而是直接R
。
所以你要将Observable
归还Subscriber
的{{1}},而不是它的事件。
onNext
:
flatMap
这是伪代码,但我希望你明白这个想法:
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)Zip
个对象Pair
运算符(使用Pair
运算符)zip
flatMap
Pair
函数返回合成对象(记住,someLogic()
应该返回someLogic
而不是R
)暗示未来: 首先尝试不使用lambda表达式编写它。然后您可以看到输入和输出参数,因此编写代码更容易。然后用lambda表达式重写它。
答案 1 :(得分:1)
重要的是Observable在订阅之前不会被执行。
因此,为了解释发生了什么,第一个Observable.zip
被赋予了组合函数(callApiA(),callApiB()) -> Observable<Something>
,因此它产生了Observable<Observable<Something>>
。
observable作为元素发送,从未订阅过。
要修复它,您需要展平可观察流:Observable.zip(...).flatmap(s -> s)
。这会将流展平为Observable<Something>
并订阅内部可观察数据。