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

Jer*_*rth 7 java android observable retrofit rx-android

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

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

获得用户很简单:

// 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);
}
Run Code Online (Sandbox Code Playgroud)

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

我是RX的新手.我看过的文件过去,使用各种方法,例如尝试flatMap()zip,不过,我还没有找到转换器或组合的确切组合使之成为现实.

rci*_*ati 6

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

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")
        ));
    }
}
Run Code Online (Sandbox Code Playgroud)

宠物类:

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 + '\'' +
                '}';
    }
}
Run Code Online (Sandbox Code Playgroud)

用户类:

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 +
                '}';
    }
}
Run Code Online (Sandbox Code Playgroud)

全部放在一起:

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());
                }
            }
        });
Run Code Online (Sandbox Code Playgroud)

它产生:

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'}]}
Run Code Online (Sandbox Code Playgroud)

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