2016-11-18 41 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>並訂閱內部可觀察。