无法构建此Observable

时间:2017-02-27 15:19:30

标签: rx-java

要构建完整的User实体,我需要执行以下任务:

  1. UserResponse
  2. 获取userId(REST API响应)
  3. List<Role>
  4. 获取userId
  5. Address
  6. 获取UserResponse.addressId
  7. UserUserResponse以及List<Role>构建Address
  8. 我试过了:

    public Observable<User> getUserById(String userId) {    
        return Observable.zip(getUserResponse(userId), getRoles(userId), new Func2<UserResponse, List<Role>, User>() {
            @Override
            public User call(UserResponse response, List<Role> roles) {
                //I need the address here!
            }
    });
    

    但我不知道如何使用AddressUserResponse.addressId获取AddressRepository

    public interface AddressRepository {
        Observable<Address> getAddress(String addressId);
    }
    

    User构造函数如下所示:

    public User(String userId, Address address, List<Role> roles) { ... }
    

    我希望你理解。很难解释这个问题。

4 个答案:

答案 0 :(得分:2)

使用cache()运算符:

public Observable<User> getUserById(String userId) {  
  Observable<UserResponse> response = getUserResponse(userId).cache();
  return Observable.zip(
    response,
    response.flatMap(new Func1<UserResponse, Observable<Address>>() {
        @Override
        public Observable<Address> call(UserResponse resp) {
            return addressRepository.getAddress(resp.addressId);
        }
    }),
    getRoles(userId), new Func3<UserResponse, Address, List<Role>, User>() {
        @Override
        public User call(UserResponse resp, Address ad, List<Role> roles) {
            //Now, I have all I need to build the User =)
        }
    }
  });
}

答案 1 :(得分:1)

getUserResponse(userId).publish.autoConnect(2); 

将使它成为ConnectableObservable并且仅开始发布有2个订阅者的位置,这样您将只调用一次后端。

getUserAddress()将调用getUserResponse并从中获取地址。

现在压缩getUserResponse,getUserAddress和getRoles(userId):)

答案 2 :(得分:1)

您可以使用flatMap的变体执行类似

的操作
public Observable<User> getUserById(String userId) {  
    return Observable.zip(
          getUserResponse(userId).flatMap(new Func1<UserResponse, Observable<Address>>() {
            @Override
            public Observable<Address> call(UserResponse resp) {
                return addressRepository.getAddress(resp.addressId);
            }
          },
          new Func2<UserResponse, Address, Pair<UserResponse,Address>>() {
            @Override
            public Pair<UserResponse,Address> call(UserResponse resp, Address addr) {
                return new Pair<UserResponse,Address>(resp,addressRepository.getAddress(resp.addressId));
            }       
          }),
          getRoles(userId),
          new Func2<Pair<UserResponse, Address>, List<Role>, User>(){
            @Override
            public User call(UserResponse resp, Address ad, List<Role> roles) {
            //Now, I have all I need to build the User
            }             
          }
        );
}

答案 3 :(得分:0)

我找到了解决方案:

public Observable<User> getUserById(String userId) {  
    return Observable.zip(
        getUserResponse(userId),
        getUserResponse(userId).flatMap(new Func1<UserResponse, Observable<Address>>() {
            @Override
            public Observable<Address> call(UserResponse resp) {
                return addressRepository.getAddress(resp.addressId);
            }
        }),
        getRoles(userId), new Func3<UserResponse, Address, List<Role>, User>() {
            @Override
            public User call(UserResponse resp, Address ad, List<Role> roles) {
                //Now, I have all I need to build the User =)
            }
        }
});

任何评论将不胜感激。 “重复”调用getUserResponse(userId)是一种好习惯吗?我没有找到另一种解决方法。