2016-04-16 66 views
1

我有代碼調用2 apis併合並結果。使用改造和rxJava。使用RxJava合併結果,處理錯誤

我該如何處理它,以便如果api的某個問題出現問題,我仍然可以從api的某個工作中得到結果?

IPlaces api = adapter.create(IPlaces.class); //endpoint1 
    IPlaces api2 = adapter2.create(IPlaces.class); //endpoint2 

    Observable.combineLatest(
      api.getPlacesFrom1("key", placeId), 
      api2.getPlacesFrom2(placeId), 
     new Func2<PlaceDetailResult1, PlaceDetailResult2, MergedReviews>() { 
      @Override 
      public MergedReviews call(PlaceDetailResult placeDetailResult1, PlaceDetailResult2 placeDetailResult2) { 
       // processToMerge( placeDetailResult1, placeDetailResult2) 
       return mr; 
      } 

      }) 
      .subscribeOn(Schedulers.newThread()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new Observer<MergedReviews>() { 
       @Override 
       public void onCompleted() { 

       } 

       @Override 
       public void onError(Throwable e) { 

       } 

       @Override 
       public void onNext(MergedReviews mr) { 

        SetAdapter(mr.reviews); 
        SetPhotosAdapter(mr.photos); 
       } 
      }); 
+0

你是什麼意思「如果有問題」?是否有一個onError被調用,是否是'placeDetailResult'無效,或者沒有消息進入? –

+0

@PeterBarmettler如果其中一個Apis關閉,id仍然像其他api被使用的結果一樣。它會進入onrorror(當ia關閉一個api時),但是我仍然希望從工作api的結果被使用,但我什麼也沒有 – raklos

+1

我想問題是,如果你結合兩個observables和其中一個調用onError,組合observable也將收到onError。你的問題的答案取決於你想要多少錯誤處理。如果你不需要關注錯誤,那麼你可以簡單地使用'.onErrorResumeNext(e-> Observable.just(null))',然後在'combineLatest'的閉包中處理'null'的情況。否則'mergeDelayError'可能會有用。另見[post](http://stackoverflow.com/questions/22340744/best-practice-for-handling-onerror-and-continuing-processing)。 –

回答

1

正如評論所述,您可以將異常轉換成使用onError*null對象(或其它任何物體)。

這是一個我認爲可以捕捉您的設置的最小示例。它需要兩個整數可觀測值,它們提供一個Integer值,並以某種方式將它們組合在一起。如果其中一個觀察對象產生錯誤,則傳送另一個值,如果兩者都產生錯誤,則拋出RuntimeException。我使用zipWith而不是combineLatest,因爲這對於您的情況而言是足夠的,其中兩個可觀察值中的每一個都應該有一個值。

Observable<Integer> zipThrowing(Observable<Integer> observable1, Observable<Integer> observable2) { 
     return observable1.onErrorReturn(ex-> null) 
       .zipWith(observable2.onErrorReturn(ex->null), 
         (a,b)->{ 
          if(b == null) { 
           if(a==null){ 
            throw new RuntimeException("None of the two values are valid."); 
           } 
           return a; 
          } 
          if(a==null) { 
           return b; 
          } 
          return a+b; 
         } 
       ); 

轉化異常轉換成null值可以在某些情況下是不可接受的。如果您需要例外信息,我建議您使用包含實際值或例外的result object

+0

沒有ZipThrowing/ZipWith期望的參數是相同的類型?因爲在我的情況下,它們是2種不同的類型,它們被處理以輸出第三種類型 – raklos

+0

文檔聲明:'public final Observable zipWith(Observable <?extends T2> other, Func2 <?super T,?super T2,?擴展R> zipFunction)',所以,是的,你可以組合兩個不同類型的參數,你可以返回一個任意的類型'R'。 –