2017-08-23 1 views
1

fertig Lassen Sie uns zwei Methoden nehmen mit Rx geschrieben:andthen ausgeführt, bevor komplettierbar

Maybe<Foo> getFooFromLocal 
Single<Foo> getFooFromNetwork 

Ich möchte eine Kette schreiben, wenn wir unsere lokalen Speicher für Foo überprüfen. Wenn wir keine Foo haben, sollten wir es aus dem Netzwerk holen, dann speichern Sie es in den lokalen Speicher und wieder aus dem lokalen Speicher und übergeben Sie es an unseren Abonnenten.

storage 
      .getFooFromLocal() 
      .switchIfEmpty(network.getFooFromNetwork().map { it[0] } 
        .flatMapCompletable { storage.saveFoo(it) } 
        .andThen(storage.getFooFromLocal())) 
        .subscriber(/**/) 

Das Problem ist, dass andThen Teil vor komplettierbar in flatMapCompletable vergangen abgeschlossen ist. Ich habe herausgefunden, dass ich dieses Problem loswerden kann, wenn ich in Maybe.defer{} einpacken. Aber nach der Dokumentation von andThen es

Gibt ein Maybe, die zu diesem komplettierbar abonnieren werden.

Und vielleicht ist schon

eine latente Stellt Berechnung und Emission eines vielleicht Wertes oder Ausnahme

Die Frage ist also, warum mein andThen Teil Lauf vor komplettierbar fertig. Und was ist der beste und eleganteste Weg solche Ketten zu schreiben.

Anrufliste:

06:05:58.803 getFooFromLocal 
06:05:58.804 getFooFromLocal 
06:05:58.804 getFooFromNetwork 
06:05:59.963 saveFoo 
+0

Ihr 'storage.getFooFromLocal()' wird wahrscheinlich über 'Maybe.just (cachedValue) 'implementiert, das ausgeführt wird, bevor eine RxJava-Aktivität überhaupt gestartet wurde. – akarnokd

+0

GetFooFromLocal implementiert über 'Maybe.create' Hier ist der Code der vielleicht Erstellung ' Maybe.create {s -> if (this! = Null) s.onSuccess (this); s.onComplete()} ' – Sunstrike

+0

' storage.getFooFromLocal() 'erscheint zweimal in Ihrer Codebasis, warum denken Sie,' andThen' ist verantwortlich? – akarnokd

Antwort

0

Dies funktioniert für mich:

public class AndThenTest { 

    Integer value; 

    @Test 
    public void test() { 
     getFromLocal() 
     .switchIfEmpty(getFromNetwork() 
       .flatMapCompletable(v -> saveFoo(v)) 
       .andThen(getFromLocal())) 
     .doOnSuccess(e -> System.out.println("Success: " + e)) 
     .test() 
     .awaitDone(5, TimeUnit.SECONDS) 
     .assertResult(10); 
    } 

    Maybe<Integer> getFromLocal() { 
     return Maybe.fromCallable(() -> { 
      System.out.println("FromLocal called"); 
      return value; 
     }); 
    } 

    Single<Integer> getFromNetwork() { 
     return Single.fromCallable(() -> { 
      System.out.println("FromNetwork called"); 
      return 10; 
     }).delay(100, TimeUnit.MILLISECONDS) 
       ; 
    } 

    Completable saveFoo(Integer v) { 
     return Completable.fromRunnable(() -> { 
      System.out.println("SaveFoo called"); 
      value = v; 
     }); 
    } 
} 

und Drucke:

FromLocal called 
FromNetwork called 
SaveFoo called 
FromLocal called 
Success: 10 

So ist meine Vermutung, dass ein Fehler in einem der Verfahren gibt es du zeigst nicht.

Verwandte Themen