2015-12-22 4 views
6

Wir verwenden ReactiveX und Retrofit in unserem Netzwerk-Stack, um alle API-Anfragen asynchron zu bearbeiten.Wie können mehrere Anfragen zum Auffüllen von Modellen mit RXJava Observables behandelt werden?

Unser Ziel ist es, eine Methode zu erstellen, die eine vollständig aufgefüllte Sammlung von User Modellen zurückgibt. Jedes User Modell hat eine Liste von Pet Objekten. Wir können alle User Modelle mit einer Anfrage abholen. Die Modelle Pet müssen jedoch unter User angefordert werden.

Erster Anwender ist einfach:

// Service.java 
@GET("users/?locationId={id}") 
Observable<List<User>> getUsersForLocation(@Path("id") int locationId); 

@GET("pets/?userId={id}") 
Observable<List<Pet>> getPetsForUser(@Path("id") int userId); 

// DataManager.java 
public Observable<List<User>> getUsersForLocation(int locationId) { 
    return api.getUsersForLocation(locationId); 
} 

public Observable<List<Pet>> getPetsForUser(int userId) { 
    return api.getPetsForUser(userId); 
} 

Wir möchten etwas bequeme (RX-Stil) Art und Weise der Schleife durch die User Liste finden, holt die Pet s für die einzelnen Benutzer, um sie zu den User zuweisen und schließlich die Observable<List<User>> zurückgeben.

Ich bin ziemlich neu in RX. Ich habe mir die Dokumentation angeschaut und verschiedene Methoden wie flatMap() und zip ausprobiert, allerdings muss ich noch die genaue Kombination von Transformationen oder Combinern finden, um das zu erreichen.

+2

In dieser Präsentation tut Jake Wharton genau das: https://goo.gl/01Evkm – rciovati

+0

Danke für den Link. Ich verwende derzeit Java 7 und die Verwendung von Lambdas in dieser Präsentation verdeckt, was in diesen Methodenaufrufen an flatMap() geschieht. Irgendwelche Einsichten? – JeremyFromEarth

Antwort

5

Ich schrieb eine kleine Beispiel-App, die das macht, was Sie erreichen wollen. Hier werden die Komponenten:

public class Datasource { 

    public Observable<List<User>> users() { 
     return Observable.just(Arrays.asList(
       new User("1", "Foo"), new User("2", "Bar") 
     )); 
    } 

    public Observable<List<Pet>> pets(User user) { 
     return Observable.just(Arrays.asList(
       new Pet(user.getName() + "'s cat"), 
       new Pet(user.getName() + "'s dog") 
     )); 
    } 
} 

Pet Klasse:

public class Pet { 
    private String mName; 

    public Pet(String name) { 
     mName = name; 
    } 

    public String getName() { 
     return mName; 
    } 

    @Override 
    public String toString() { 
     return "Pet{" + 
       "mName='" + mName + '\'' + 
       '}'; 
    } 
} 

Benutzerklasse:

public class User { 

    private String mName; 
    private String mId; 
    private List<Pet> mPetList; 

    public User(String id, String name) { 
     this(id, name, Collections.<Pet>emptyList()); 
    } 

    public User(String id, String name, List<Pet> pets) { 
     mName = name; 
     mId = id; 
     mPetList = pets; 
    } 

    public String getName() { 
     return mName; 
    } 

    public String getId() { 
     return mId; 
    } 

    public User copyWithPets(List<Pet> pets) { 
     return new User(mId, mName, pets); 
    } 

    @Override 
    public String toString() { 
     return "User{" + 
       "mName='" + mName + '\'' + 
       ", mId='" + mId + '\'' + 
       ", mPetList=" + mPetList + 
       '}'; 
    } 
} 

alle zusammen:

datasource.users() 
     .flatMap(new Func1<List<User>, Observable<User>>() { 
      @Override 
      public Observable<User> call(List<User> users) { 
       return Observable.from(users); 
      } 
     }) 
     .flatMap(new Func1<User, Observable<User>>() { 
      @Override 
      public Observable<User> call(final User user) { 
       return datasource.pets(user) 
         .map(new Func1<List<Pet>, User>() { 
          @Override 
          public User call(List<Pet> pets) { 
           return user.copyWithPets(pets); 
          } 
         }); 
      } 
     }) 
     .toList() 
     .subscribe(new Action1<List<User>>() { 
      @Override 
      public void call(List<User> users) { 
       for (User user : users) { 
        Log.d(TAG, "user: " + user.toString()); 
       } 
      } 
     }); 

Es produziert:

D/MainActivity: user: User{mName='Foo', mId='1', mPetList=[Pet{mName='Foo's cat'}, Pet{mName='Foo's dog'}]} 
D/MainActivity: user: User{mName='Bar', mId='2', mPetList=[Pet{mName='Bar's cat'}, Pet{mName='Bar's dog'}]} 

Wenn es Sie nicht beantwortet Frage bitte posten Sie aktuelle Datenmodell für Benutzer und Haustier.

+0

Genial, wie wow! Ihr Beitrag hat mir auch geholfen! Danke mein Herr! :) – rxDroid

Verwandte Themen