如何使用RXJava Observables处理用于填充模型的多个请求? [英] How can multiple requests used to populate models be handled using RXJava Observables?

查看:188
本文介绍了如何使用RXJava Observables处理用于填充模型的多个请求?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We are using ReactiveX and Retrofit in our network stack to handle all API requests in an asynchronous way.

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

Our goal is to create one method that will return a completely populated collection of User models. Each User model has a list of Pet objects. We can fetch all of the User models with one request. However, Pet models need to be requested per 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);
}

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

We would like to find some convenient (RX style) way of looping through the User list, fetching the Pets for that each user, assigning them to the User and ultimately returning the Observable<List<User>>.

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

I am fairly new to RX. I've looked over the documentation and have tried using various methods such as flatMap() and zip, however, I have yet to find the exact combination of transforms or combiners to make it happen.

推荐答案

我写了一个小样本应用程序来实现你想要实现的目标。这里的组件:

I wrote a small sample app that makes what you are trying to achieve. Here the components:

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")
        ));
    }
}

宠物等级:

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

全部放在一起:

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());
                }
            }
        });

它产生:

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

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

If it doesn't answer you question please post you actual datamodel for User and Pet.

这篇关于如何使用RXJava Observables处理用于填充模型的多个请求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆