[英]How to process items emitted by an Observable with access to values from another?
I need to perform an async call_1
, catch its Observable reply_1
, then make another async call_2
and when processing its reply_2
I also need access to the reply_1
. 我需要执行一个异步
call_1
,捕获其可观察到的reply_1
,然后再进行一次异步call_2
,在处理其reply_2
我还需要访问reply_1
。
I've tried something like: 我已经尝试过类似的东西:
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);
}
});
}
I'm still having problem compiling this method because of final
issues of game
. 由于
game
的final
问题,我仍然无法编译这种方法。
Is this the right way to do work on this problem or there is a much natural way to accomplish what I'm trying to. 这是解决此问题的正确方法,还是有一种很自然的方法来完成我要尝试的工作。
If I understand what you want to do correctly, I think the natural way to solve this would be zip
: 如果我了解您要正确执行的操作,则认为解决此问题的自然方法是
zip
:
You have two Observables that asynchronously emit their results, namely ebs
and the return value of context.findGame(...)
. 您有两个Observables异步发出其结果,即
ebs
和context.findGame(...)
的返回值。
You can combine their result by doing something like this: 您可以通过执行以下操作来组合其结果:
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;
}
});
}
The Func2 - the third argument of zip - will be called when both of your source Observables have called their onNext
. 当两个源Observable都调用它们的
onNext
时,将调用Func2-zip的第三个参数。 It will be used to combine the values they emit to a new value of type Game and this will be emitted to subscribers of the resulting Observable. 它将用于将它们发出的值合并为Game类型的新值,并将其发送给所得Observable的订户。
EDIT: Some more information... 编辑:更多信息...
Note that I changed the return of call() from Observable<Game>
to just Game. 请注意,我将call()的返回值从
Observable<Game>
更改为Game。 Otherwise the result of zip would not have been an Observable<Game>
but an Observable<Observable<Game>>
. 否则,zip的结果将不是
Observable<Game>
而是Observable<Observable<Game>>
。 Unlike map and flatMap there is only zip in rx - no flatZip. 与map和flatMap不同,rx中只有zip-没有flatZip。 But since you always want to emit exactly one game for each pair of input items (one from ebs, one from gameObs) that's not a problem in this case.
但是,由于您始终希望为每对输入项准确地发布一个游戏(一个来自ebs,一个来自gameObs),所以在这种情况下这不是问题。
Also, the call() of the Func2 could now be further simplified to just: 而且,现在可以将Func2的call()进一步简化为:
@Override
public Game call(RxMessage<byte[]> gameRawReply, RxMessage<byte[]> t1) {
switch(game_model) {
case SINGLE: {
return singleGames.get(0);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.