我要执行以下任务:
我需要发出2个observable(obs1和obs2)来处理它们的结果,然后调用另一个observable(obs3)并处理它的结果,如果可能的话,在处理obs3的结果时可以访问obs1和obs2的结果。
这是我的草案代码,它不能解决问题,我该如何改变它。
public void executeFind(String session_id, long template_id, GameModelType game_model) {
Observable<RxMessage<byte[]>> userObs = context.getUser(session_id);
Observable<Game> gameObs = context.findGame(template_id, game_model, GameStateType.WAITING);
Observable.zip(userObs, gameObs, new Func2<RxMessage<byte[]>, Game, GameObject>() {
@Override
public GameObject call(RxMessage<byte[]> userRawReply, ActiveGame game) {
..
..
return context.updateGame(game.getGameData())
.subscribe(new Action1<GameObject>() {
@Override
public void call(GameObject updateReply) {
..
..
}
});
return userReply;
}
});
}
这实际上不起作用 - 我可以编写一个代码,它对每个Observable使用.flatMap \ subscribe的显式调用,但会导致很多嵌套调用,这显然对框架的使用很差。
解决这个问题的正确方法是什么?
谢谢!
修改
我发现这个解决方案可行,但我仍然想知道是否有一种“更清洁”的方法来实现这个目标:
public void executeFind(ReplyMessage<JsonObject> replyObj, String session_id, long template_id, GameModelType game_model) throws CommandException {
rx.Observable<GameObject> userObs = context.getUser(session_id);
rx.Observable<Game> gameObs = context.findGame(template_id, game_model, GameStateType.WAITING);
rx.Observable.zip(userObs, gameObs, new Func2<GameObject, Game, List<Object>>() {
@Override
public List<Object> call(GameObject userReply, Game game) {
User user = ...;
final List<Object> results = new ArrayList<Object>(3);
results.add(ErrorCodes.STATUS_OK);
results.add(user);
results.add(game);
context.updateGame(game.getGameData()).subscribe(new Action1<GameObject>() {
@Override
public void call(GameObject updateReply) {
...
}
});
return results;
}
}).subscribe(new Action1<List<Object>>() {
@Override
public void call(List<Object> results) {
int status = (int) results.get(0);
User user = (User) results.get(1);
Game game = (Game) results.get(2);
}
});
}
答案 0 :(得分:1)
我会用以下想法编写这个东西。如果map
与您的用例相关,则flatMap
可以替换为public void executeFind(ReplyMessage<JsonObject> reply_obj, String session_id, long template_id, GameModelType game_model) throws CommandException {
Observable<GameObject> userObs = context.getUser(session_id);
Observable<Game> gameObs = context.findGame(template_id, game_model, GameStateType.WAITING);
Observable.zip(userObs, gameObs, (userReply, game) -> {
User user = ...;
return GameOfUser.gameFound(game, user);
}).map(gou -> {
context.updateGame(gou.gameData()).susbcribe(...);
return gou;
}).subscribe(gou -> ...);
}
。另请注意,我只使用了Java 8 lambdas语法,但为了更具可读性,我强烈建议您为每个函数/操作提供简单且命名良好的方法(并将它们与方法引用一起使用),因为它将提高代码的可理解性(那是我们在mockito上做的,但是每个人都应该在自己的代码库中做到这一点)。
{{1}}