2016-07-27 77 views
1

我想通過多個REST API異步檢索數據。我使用rxJava擴展在Android上使用Retrofit,即通過訂閱Observable來執行任何GET請求。有條件的可觀察鏈

正如我所說,我有多個源API,所以當第一個源不會產生所需的結果時,我想嘗試下一個,如果這也失敗了,再次嘗試下一個等等,直到所有源都有被查詢或找到結果。

我掙扎,因爲我不知道哪個運營商可以實現這種行爲,也有一些制約因素兌現把這種方法爲正確使用觀測值:

  • 時,結果發現,其餘的API,如果有的話,不應該被查詢
  • 其他組件取決於查詢的結果,我希望它們在啓動請求時獲得一個Observable,所以這個Observable可以通知它們完成請求
  • 我需要保留對上述Observable的引用,因爲相同的請求c可能會在完成前多次創建,在這種情況下,我只在第一次啓動時才啓動它,並且隨後的請求僅獲取通知請求完成時的Observable。

我剛開始只用一個API查詢和用於相關組件的請求,並隨後通知如下:

private Observable<String> loadData(int jobId) { 

    final ConnectableObservable<String> result = Async 
      .fromCallable(() -> getResult(jobId)) 
      .publish(); 

    getRestRequest() 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(
        dataHolder -> { 
         if (dataHolder.getData() != null && !dataHolder.getData().isEmpty()) { 
          saveData(dataHolder.getData()); 
         } else { 
          markNotFound(dataHolder); 
         } 
        }, 
        error -> currentJobs.remove(jobId), 
        () -> { 
         currentJobs.remove(jobId); 
         result.connect(); 
        }); 

    return result; 
} 

此代碼才被要求的第一請求,則返回的可觀測結果將被保存在currentJobs和後續請求僅將在不觸發請求的情況下獲取Observable。

任何幫助,高度讚賞。

回答

0

假設你有一個觀測值組,每次認購時重新連接:

List<Observable<Result>> suppliers = ... 

接下來,你需要做的就是順理成章的事情:

​​
+0

我認爲這是要走的路。我發現了一個類似的方法[這裏](http://blog.danlew.net/2015/06/22/loading-data-from-multiple-sources-with-rxjava/)。 concat()和from()之間是否有任何功能差異?在鏈接的博客中,他們強調使用concat()時,訂閱僅在需要時進行,是否也適用於from()? concatMap()的用途是什麼? – DerBob

+0

'from'只是從特定源創建一個Observable。 'concat'需要多個Obserbles,並且只有在前一個結束時纔開始從下一個中獲取項目。 'concatMap'會更進一步(不完全等同於concat + map)。 –

0

使用.onErrorResumeNext,並假設每個可觀察服務可返回0或1個元素,如果沒有元素髮射,則使用first發出錯誤:

Observable<T> a, b, c; 
... 
a.first().onErrorResumeNext(t -> b.first()) 
.onErrorResumeNext(t -> c.first()) 
.onErrorResumeNext(t -> d.first()) 
... 
+0

當其中一個請求完成而沒有找到所請求的數據時,它將返回一個emptpy dataHolder。這不會導致錯誤被拋出,所以這種方法不會按需要工作。 – DerBob

+0

我已經用'first'來更新答案來處理你的額外需求 –