2017-02-23 4 views
1

: Ich bin in rxjava, also bitte nicht streng sein ...Benutzerdefinierte rx Func1 für Retrofit-Response-Code Handhabung

Ich habe Anfrage Läuse nächste:

Observable<Login>login(String l, String p){ 
     return api.loginUser(l,p) 
       .subscribeOn(Schedulers.io()) 
       .observeOn(AndroidSchedulers.mainThread()) 
       .flatMap(new Func1<Response<Login>, Observable<? extends Login>>() { 
        @Override 
        public Observable<? extends Login> call(Response<Login> r) { 
         switch (r.code()){ 
          case 200: 
           requestOk(r); 
           break; 
          case 202: 
           //need to Repeat 
           login.timeout(2000,TimeUnit.Milliseconds); 
           break; 
          default: 
           // 
         } 
        } 
       }); 
    } 

Observable<Login> requestOk(final Response<Login> r){ 
      return Observable.create(new Observable.OnSubscribe<Login>(){ 
       @Override 
       public void call(Subscriber<? super Login> subscriber) { 
        if (subscriber.isUnsubscribed()) return; 
        subscriber.onNext(r.body()); 
        subscriber.onCompleted(); 
       } 
      }); 
     } 

Es funktioniert ok. Aber es wird viele andere Anfragen geben, bei denen ich im Falle einer Wiederholung den Anforderungscode überprüfen muss. Ich habe versucht, benutzerdefinierte Func1 erstellen

So - universell für alle Anfrage:

private <T>Func1<? super Response<T>, ? extends Observable<? extends T>> customFunc(final Observable<T> o) { 
     return new Func1<Response<T>, Observable<? extends T>>() { 
      @Override 
      public Observable<? extends T> call(Response<T> r) { 
       switch (r.code()){ 
        case 200: 
         // 
         break; 
        case 202: 
         //need to Repeat 
         return o.timeout(2000,TimeUnit.Milliseconds); 
         break; 
        default: 
         // 
       } 
      }; 
     }; 
    } 

ich stecken bin mit Strom beobachtbar von Login beobachtbaren in customFunc setzen.

Ich glaube, es muss einen anderen, einfacheren und korrekten Weg geben, wie man das macht. Wir freuen uns über jede Hilfe!

Antwort

4

können Sie Transformer verwenden, um einen generischen Statuscode Verifizierer zu erstellen:

class StatusCodeVerifierTransformer<T> implements Observable.Transformer<Response<T>, T> { 

    @Override 
    public Observable<T> call(Observable<Response<T>> responseObservable) { 
     return responseObservable.flatMap(new Func1<Response<T>, Observable<T>>() { 
      @Override 
      public Observable<T> call(Response<T> loginResponse) { 
       switch (loginResponse.code()) { 
        case 200: 
         return Observable.just(loginResponse.body()); 
        case 202: 
         //need to Repeat 
         return Observable.error(new Status202Exception()); 
        default: 
         return Observable.error(new Exception("unknown error")); 
       } 
      } 
     }); 

    } 
} 

dieser Transformator wird jede Observable von Response<T> nehmen und es zu Observable von T verwandeln, die Fehler nach Ihrer Strategie emittiert.
Dann nutzen Sie es mit compose() Betreiber:

Observable<Login> login(String l, String p) { 
    return api.loginUser(l, p) 
      .compose(new StatusCodeVerifierTransformer<>()) 
    } 

Jetzt haben Sie eine Observable die onError mit Ihrem gewünschten Ausnahme nach Ihren Statuscode Handhabung emittieren.

Jetzt können Sie auf Fehler wiederholen wie bei jedem Observable mit retry Betreiber, zum Beispiel wie folgt aus:

api.loginUser(l, p) 
      .compose(new StatusCodeVerifierTransformer<>()) 
      .retry(new Func2<Integer, Throwable, Boolean>() { 
       @Override 
       public Boolean call(Integer retryCount, Throwable throwable) { 
        return throwable instanceof Login202Exception && retryCount < MAX_RETRY; 
       } 
      }) 

BTW, einige Kommentare:

requestOk - Sie definitiv nicht brauchen Um Observable zum einmaligen Senden eines bestimmten Werts zu erstellen, verwenden Sie einfach den Operator just(), wie im Beispiel StatusCodeVerifierTransformer. (oder für jede andere Synchronisierungsoperation, haben Sie viele Operatoren wie fromCallable(), just(), from())
Im Allgemeinen create() ist keine sichere Methode zum Erstellen eines Observable mehr.

Verwandte Themen