2017-05-05 16 views
3

RxJava 2アダプタとともにRetrofit 2を使用しています。Retrofit 2 + RxJava retryWhen

サーバは401権限を返すたびに、私はトークンをリフレッシュし、要求を再試行してください:

apiCall.retryWhen(es -> es 
    .flatMap(e -> { 
     if (isUnauthorizedException(e)) { 
      return refreshToken(); 
     } 

     return Flowable.<User>error(e); 
    })); 
refreshTokenは、簡単な改造コールで

:今

public Flowable<User> refreshToken() { 
    return retrofitService.login(userCredentials); 
} 

、私は制限したいですそのようなリフレッシュが可能な回数。しかし、単にtake(1)を追加するだけでは機能しません。なぜなら、retryWhenはonNextの直後にonCompletedを受信し、要求を取り消してから再試行するからです。

当然、私はtake(2)を実行して目的の効果を達成することができますが、ハックのようです。

Rx演算子を使用して実現する最もエレガントな方法は何ですか?また、「アサーション」ロジックを持つオペレータがあります(フラットマップにifを取り除くため)?

また、私はOkHttpインターセプタを使用して同じことを達成できることを認識していますが、私はRetrofit-RxJavaソリューションに興味があります。

+0

「再試行」を試しましたか? - '' public Flowable refreshToken(){ 戻り値retrofitService.login(userCredentials).retry(3); } '' - エラーを出す前に最大3回再試行します。 – Fred

答えて

1

文書
の素晴らしい例があります。これは、待機する秒数を増やすたびに3回再試行します。

ObservableSource.create((Observer<? super String> s) -> { 

    System.out.println("subscribing"); 
    s.onError(new RuntimeException("always fails")); 

}).retryWhen(attempts -> { 

    return attempts.zipWith(ObservableSource.range(1, 3), 
    (n, i) -> i).flatMap(i -> { 

    System.out.println("delay retry by " + i + " second(s)"); 
    return ObservableSource.timer(i, TimeUnit.SECONDS); 

    }); 
}).blockingForEach(System.out::println); 

出力は:

  • (3秒単位で2秒(S)
  • 加入遅延リトライによって1秒(s)は
  • 加入遅延リトライによって
  • 遅延リトライを購読しますs)
  • サブスクライブ

この例は、要件に応じて変更できます。

関連する問題