带 rx 的条件查询串联
Conditional query concatenation with rx
我遇到了以下问题。我有一个从具有 属性 isMember 的服务器请求的基本对象。
如果 属性 为真,我想向端点 1、2 和 3 发出请求。
如果 属性 为假,我只想向端点 1 发出请求。
我在下面写了一个基本的用例示例,其中包含所有相关 类
显示程序流程。这个问题的相关部分在评论的 UserViewModel::loadData 中。
我不知道如何用 Rx 实现这个...你能给我一些提示吗?
干杯!
interface Controller {
Observable<BaseInfoDto> getBaseInfo(long id);
Observable<AccountDto> getAccount(long id);
Observable<MemberFriendsDto> getFriends(long id);
Observable<MemberLikesDto> getLikes(long id);
}
...
class UserModel {
private final long userId;
private BaseInfoDto baseInfo;
private AccountDto accountData;
private MemberFriendsDto friends:
private MemberLikesDto likes;
public UserModel(long userId) {
this.userId = userId;
}
public long getId() {
return userId;
}
public BaseInfoDto getBaseInfo() {
return baseInfo;
}
public void setBaseInfo(BaseInfoDto baseInfo) {
this.baseInfo = baseInfo;
}
// … etc.
}
...
class UserViewModel {
private final Controller controller;
private final UserModel userModel;
public UserViewModel(Controller controller, long userId) {
this.controller = controller;
userModel = new UserModel(userId);
}
public Completable loadData() {
return controller.getBaseInfo(userModel.getId())
.doOnNext(this::setBaseInfo)
.toCompletable()
.mergeWith(loadAccountData())
// if, after BaseInfoDto arrived, BaseInfoDto::isMember is true
// load the following other queries
// else stop after merging loadAccountData
.mergeWith(loadFriends)
.mergeWith(loadLikes)
.doOnTerminate(() -> {
// notify data bindings
});
}
private Completable loadAccountData() {
return controller.getAccount(userModel.getId())
.doOnNext(this::setAccountData)
.toCompletable()
.onErrorComplete();
}
private Completable loadFriendsData() {
// like loadAccountData
}
private Completable loadLikesData() {
// like loadAccountData
}
private void setBaseInfo(BaseInfoDto baseInfo) {
userModel.setBaseInfo(baseInfo);
}
private void setAccountData(AccountDto accountData) {
userModel.setAccountData(accountData);
}
// … etc.
}
...
class UserDetailsView {
private final long selectedUser;
private final ThreadManager threadManager;
private final UserViewModel viewModel;
public UserDetailsView(long selectedUser, ThreadManager threadManager) {
this.selectedUser = selectedUser;
this.threadManage = threadManager;
viewModel = new UserViewModel(selectedUser);
}
void onViewInstantiated() {
// lots of stuff happens
loadUserData();
}
private void loadUserData() {
viewModel.loadData()
.observeOn(threadManager.getMainThread())
.subscribe(this::showError, this::bindUserData);
}
private void showError() {
// foo
}
private void bindUserData() {
// bar
}
}
...只是为了完整
interface ThreadManager {
Thread getMainThread();
}
根据isMember
结果使用flatMap
:
controller
.getBaseInfo(userModel.getId())
.flatMap(info -> {
if (info.isMember())
return endpoint1
.mergeWith(endpoint2)
.mergeWith(endpoint3);
else
return endpoint1;
})...
我遇到了以下问题。我有一个从具有 属性 isMember 的服务器请求的基本对象。
如果 属性 为真,我想向端点 1、2 和 3 发出请求。
如果 属性 为假,我只想向端点 1 发出请求。
我在下面写了一个基本的用例示例,其中包含所有相关 类 显示程序流程。这个问题的相关部分在评论的 UserViewModel::loadData 中。
我不知道如何用 Rx 实现这个...你能给我一些提示吗?
干杯!
interface Controller {
Observable<BaseInfoDto> getBaseInfo(long id);
Observable<AccountDto> getAccount(long id);
Observable<MemberFriendsDto> getFriends(long id);
Observable<MemberLikesDto> getLikes(long id);
}
...
class UserModel {
private final long userId;
private BaseInfoDto baseInfo;
private AccountDto accountData;
private MemberFriendsDto friends:
private MemberLikesDto likes;
public UserModel(long userId) {
this.userId = userId;
}
public long getId() {
return userId;
}
public BaseInfoDto getBaseInfo() {
return baseInfo;
}
public void setBaseInfo(BaseInfoDto baseInfo) {
this.baseInfo = baseInfo;
}
// … etc.
}
...
class UserViewModel {
private final Controller controller;
private final UserModel userModel;
public UserViewModel(Controller controller, long userId) {
this.controller = controller;
userModel = new UserModel(userId);
}
public Completable loadData() {
return controller.getBaseInfo(userModel.getId())
.doOnNext(this::setBaseInfo)
.toCompletable()
.mergeWith(loadAccountData())
// if, after BaseInfoDto arrived, BaseInfoDto::isMember is true
// load the following other queries
// else stop after merging loadAccountData
.mergeWith(loadFriends)
.mergeWith(loadLikes)
.doOnTerminate(() -> {
// notify data bindings
});
}
private Completable loadAccountData() {
return controller.getAccount(userModel.getId())
.doOnNext(this::setAccountData)
.toCompletable()
.onErrorComplete();
}
private Completable loadFriendsData() {
// like loadAccountData
}
private Completable loadLikesData() {
// like loadAccountData
}
private void setBaseInfo(BaseInfoDto baseInfo) {
userModel.setBaseInfo(baseInfo);
}
private void setAccountData(AccountDto accountData) {
userModel.setAccountData(accountData);
}
// … etc.
}
...
class UserDetailsView {
private final long selectedUser;
private final ThreadManager threadManager;
private final UserViewModel viewModel;
public UserDetailsView(long selectedUser, ThreadManager threadManager) {
this.selectedUser = selectedUser;
this.threadManage = threadManager;
viewModel = new UserViewModel(selectedUser);
}
void onViewInstantiated() {
// lots of stuff happens
loadUserData();
}
private void loadUserData() {
viewModel.loadData()
.observeOn(threadManager.getMainThread())
.subscribe(this::showError, this::bindUserData);
}
private void showError() {
// foo
}
private void bindUserData() {
// bar
}
}
...只是为了完整
interface ThreadManager {
Thread getMainThread();
}
根据isMember
结果使用flatMap
:
controller
.getBaseInfo(userModel.getId())
.flatMap(info -> {
if (info.isMember())
return endpoint1
.mergeWith(endpoint2)
.mergeWith(endpoint3);
else
return endpoint1;
})...