如何使用RXJava Observables处理用于填充模型的多个请求?

我们在网络堆栈中使用ReactiveX和Retrofit以异步方式处理所有API请求。

我们的目标是创建一个返回完全填充的User模型集合的方法。 每个User模型都有一个Pet对象列表。 我们可以通过一个请求获取所有User模型。 但是,每个User需要请求Pet模型。

获得用户很简单:

 // Service.java @GET("users/?locationId={id}") Observable<List> getUsersForLocation(@Path("id") int locationId); @GET("pets/?userId={id}") Observable<List> getPetsForUser(@Path("id") int userId); // DataManager.java public Observable<List> getUsersForLocation(int locationId) { return api.getUsersForLocation(locationId); } public Observable<List> getPetsForUser(int userId) { return api.getPetsForUser(userId); } 

我们希望找到一些方便的(RX风格)循环User列表的方法,为每个用户获取Pet ,将它们分配给User并最终返回Observable<List>

我对RX很新。 我查看了文档,并尝试使用各种方法,如flatMap()zip ,但是,我还没有找到变换或组合的确切组合来实现它。

我写了一个小样本应用程序,它可以实现您想要实现的目标。 这里的组件:

 public class Datasource { public Observable> users() { return Observable.just(Arrays.asList( new User("1", "Foo"), new User("2", "Bar") )); } public Observable> pets(User user) { return Observable.just(Arrays.asList( new Pet(user.getName() + "'s cat"), new Pet(user.getName() + "'s dog") )); } } 

宠物类:

 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 + '\'' + '}'; } } 

用户类:

 public class User { private String mName; private String mId; private List mPetList; public User(String id, String name) { this(id, name, Collections.emptyList()); } public User(String id, String name, List pets) { mName = name; mId = id; mPetList = pets; } public String getName() { return mName; } public String getId() { return mId; } public User copyWithPets(List pets) { return new User(mId, mName, pets); } @Override public String toString() { return "User{" + "mName='" + mName + '\'' + ", mId='" + mId + '\'' + ", mPetList=" + mPetList + '}'; } } 

全部放在一起:

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

它产生:

 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'}]} 

如果它没有回答你的问题,请发布用户和宠物的实际数据模型。