2016-11-18 91 views
1

我试图从一个API调用链构造一个observable,但我无法让它工作。我有四个API调用ApiAApiBApiCApiD返回观察使用RxJavaCallAdapterFactory。必须先调用ApiAApiB,然后在两者都执行后调用ApiC和ApiD。在执行了最后两个View之后初始化。我正在使用zip运算符来等待电话完成,我不确定这是要走的路,但我对RxJava颇为陌生,所以如果还有其他更好的方法,请告诉我。 下面是我的代码注释表示在我被困RxJava使用zip链接多个调用

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(); 
      })); 
} 

,并鉴于我只是subsribe这种方法

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

我又是相当新的RxJava所以任何帮助将不胜感激。谢谢

+0

你确定呼叫没有在主线程上运行吗?你可以在'callApiX()'上添加'.subscribeOn(Schedulers.io())'。你有日志吗? –

+0

所有调用都在Schedulers.io()上,并且没有错误或警告 – TheJudge

回答

0

你是在正确的轨道上。

但是,要知道,.zip最后一个参数,Func没有返回Observable<R>从它的call功能,但R直接。

所以你正在返回ObservableSubscriberonNext而不是它的事件。

之间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() 
      })); 

这是伪代码,但是我希望你的想法:

  1. Zip第2个呼叫(A,B)
  2. 返回Pair从这些功能返回的对象
  3. 转换Pair使用zip操作者(使用flatMap操作者)
  4. 撰写本Pair与下一个2个呼叫(C,d)
  5. 返回从someLogic()功能组成对象(记住,这someLogic应返回R和不Observable<R>

提示未来: 请先尝试使用lambda表达式编写它。然后你可以看到输入和输出参数,所以编写代码更容易。然后用lambda表达式重写。

+0

感谢您的回答,但我仍然卡在同一个地方,前两个调用被执行,然后什么也没有 – TheJudge

0

重要的部分是Observable不会被执行,直到他们订阅。

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

要解决这个问题,您需要将可观察的流变平:Observable.zip(...).flatmap(s -> s)。这将流平整为Observable<Something>并订阅内部可观察。