Java 发射2个观测值,处理结果,然后发射另一个

Java 发射2个观测值,处理结果,然后发射另一个,java,node.js,java-8,rx-java,vert.x,Java,Node.js,Java 8,Rx Java,Vert.x,我要执行以下任务: 我需要发出2个可观察对象(obs1和obs2)处理其结果,然后调用另一个可观察对象(obs3)并处理其结果,如果可能,在处理obs3的结果时,可以访问obs1和obs2的结果 这是我的草稿代码,它不起作用,我如何修改它 public void executeFind(String session_id, long template_id, GameModelType game_model) { Observable<RxMessage<byte[]>

我要执行以下任务:

我需要发出2个可观察对象(obs1和obs2)处理其结果,然后调用另一个可观察对象(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; 
     }
   });
 }
public void executeFind(字符串会话\u id、长模板\u id、GameModelType游戏\u模型){
Observable userObs=context.getUser(会话标识);
Observable gameObs=context.findGame(模板id、游戏模型、GameStateType.WAITING);
zip(userObs、gameObs、newfunc2(){
@凌驾
公共游戏对象调用(RxMessage userRawReply,ActiveGame游戏){
..
..
返回context.updateGame(game.getGameData())
.订阅(新操作1(){
@凌驾
公共无效调用(GameObject updateReply){
..
..
}
});
返回userReply;
}
});
}
这实际上不起作用-我可以编写一个代码,它使用显式调用.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);

        }

    });
}
public void executeFind(ReplyMessage replyObj,String session_id,long template_id,GameModelType game_model)抛出CommandException{
rx.Observable userObs=context.getUser(会话id);
rx.Observable gameObs=context.findGame(模板id、游戏模型、GameStateType.WAITING);
zip(userObs、gameObs、newfunc2(){
@凌驾
公共列表调用(GameObject用户回复,游戏){
用户=。。。;
最终列表结果=新的ArrayList(3);
结果.添加(错误代码.状态\正常);
结果。添加(用户);
结果。添加(游戏);
context.updateGame(game.getGameData()).subscribe(newaction1()){
@凌驾
公共无效调用(GameObject updateReply){
...
}
});
返回结果;
}
}).订阅(新操作1(){
@凌驾
公共作废调用(列出结果){
int status=(int)results.get(0);
User=(User)results.get(1);
游戏=(游戏)结果。获得(2);
}
});
}

我会根据以下想法编写代码。可能是
map
可以替换为
flatMap
,如果这与您的用例相关。还要注意,我只使用了Java8Lambdas语法,但为了更具可读性,我强烈建议您为这些函数/操作中的每个函数/操作使用简单且命名良好的方法(并将它们与方法引用一起使用),因为这将提高代码的可理解性(这是我们在mockito上所做的,但每个人都应该在自己的代码库中进行)

public void executeFind(ReplyMessage reply\u obj、字符串会话\u id、长模板\u id、GameModelType game\u model)引发CommandException{
Observable userObs=context.getUser(会话标识);
Observable gameObs=context.findGame(模板id、游戏模型、GameStateType.WAITING);
zip(userObs,gameObs,(userReply,game)->{
用户=。。。;
返回GameOfUser.gameFound(游戏,用户);
}).map(gou->{
context.updateGame(gou.gameData()).susbcribe(…);
归苟;
}).认购(gou->…);
}

这就是你想要实现的目标。Zip是故意从stream api中删除的,因此您可能需要重新思考您试图解决的问题。请查看我的“编辑”-现在可能更清楚了。如果你有更好的解决办法。。请分享…再一次,对我来说,你好像有问题。你可以自由选择随机的游戏对象和用户对象,然后突然变成用户回复。然后你得到了用户,并继续拖得更远。有些东西是。您创建的GameOfUser就像“游戏”和“用户”的包装器,它返回一个可观察到的,可以映射和订阅。我猜对了吗?是的,就是这个主意。仍然可以自由地进一步探索。请注意,rxjava邮件列表也是一个询问的好地方。有些人同时遵循SO和邮件列表。来想想你的解决方案,它和我建议的没有什么不同,不是吗??我的解决方案建立了一个列表并将其传递给订阅。是的,事实上,这在方法上是类似的,我不知道您必须处理的需求。但是这个流程比你的代码片段更重要。所以我认为这是你可能想要的更干净的方式……根据;)
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 -> ...);
}