如何处理Observable发出的项目,可以访问另一个的值?

时间:2014-10-02 16:51:44

标签: java java-8 rx-java

我需要执行异步call_1,捕获其Observable reply_1,然后创建另一个异步call_2,并在处理其reply_2时我还需要访问{{} 1}}。

我尝试过类似的事情:

reply_1

由于public rx.Observable<Game> findGame(long templateId, GameModelType game_model, GameStateType state) { rx.Observable<RxMessage<byte[]>> ebs = context.getGameTemplate(templateId); return context.findGame(templateId, state) // findGame returns rx.Observable<RxMessage<byte[]>> .flatMap(new Func1<RxMessage<byte[]>, rx.Observable<Game>>() { @Override public Observable<Game> call(RxMessage<byte[]> gameRawReply) { Game game = null; switch(game_model) { case SINGLE: { ebs.subscribe(new Action1<RxMessage<byte[]>>() { @Override public void call(RxMessage<byte[]> t1) { game = singleGames.get(0); } }); } } return rx.Observable.from(game); } }); } 的{​​{1}}问题,我仍然无法编译此方法。

这是解决这个问题的正确方法,还是有一种很自然的方法可以实现我想要的目标。

1 个答案:

答案 0 :(得分:1)

如果我理解你想要做的正确,我认为解决这个问题的自然方法是zip

你有两个异步发出结果的Observable,即ebscontext.findGame(...)的返回值。

您可以通过执行以下操作来结合他们的结果:

public rx.Observable<Game> findGame(long templateId, GameModelType game_model, GameStateType state) {

    rx.Observable<RxMessage<byte[]>> ebs = context.getGameTemplate(templateId);
    rx.Observable<RxMessage<byte[]>> gameObs = context.findGame(templateId, state);

    return Observable.zip(gameObs, ebs, new Func2<RxMessage<byte[]>, RxMessage<byte[]>, Game>() {

        @Override
        public Game call(RxMessage<byte[]> gameRawReply, RxMessage<byte[]> t1) {

            Game game = null;

            switch(game_model) {
                case SINGLE: {
                    game = singleGames.get(0);
                }
            }

            return game;
        }
    });
}

当您的源Observables的两个都调用了他们的onNext时,将调用Func2 - zip的第三个参数。它将用于将它们发出的值组合到Game类型的新值中,并将其发送给生成的Observable的订阅者。

编辑:更多信息......

请注意,我将call()的返回从Observable<Game>更改为Game。否则,zip的结果不是Observable<Game>而是Observable<Observable<Game>>。与map和flatMap不同,rx中只有zip - 没有flatZip。但是因为你总是希望为每对输入项(一个来自ebs,一个来自gameObs)只发出一个游戏,所以在这种情况下这不是问题。

此外,Func2的call()现在可以进一步简化为:

@Override
public Game call(RxMessage<byte[]> gameRawReply, RxMessage<byte[]> t1) {

    switch(game_model) {
        case SINGLE: {
            return singleGames.get(0);
        }
    }
}