Reputation: 1933
I have to execute 2 observable in parallel (don't care about their output), and when they both finished -> run another observable.
This is my solution, but I feel there are better ones:
rx.Observable<GameObject> obs1 = ...;
rx.Observable<GameObject> obs2 = ...;
rx.Observable.merge(obs1,obs2).takeLast(1)
.flatMap(mergeObj -> {
return payoutStrategy.calculatePayout(gameTemplate, gameData);
}).subscribe(results -> {
...
});
I use merge just in order to invoke the 2 obs's and then 'takeLast(1)' to ignore entering 'flatMap' twice.
This solution is far from being elegant but it works..
Any ideas how to make it better?
Thanks!
Upvotes: 4
Views: 3064
Reputation: 12097
concat
is useful for doing something on completion of something else. Because the type of Observable
returned by calculatePayout
is presumably different you cast the empty stream to its result type:
obs1.mergeWith(obs2)
.ignoreElements()
.castAs(Payout.class)
.concatWith(payoutStrategy.calculatePayout(gameTemplate, gameData))
.subscribe( ...)
By the way if obs1
and obs2
are not async sources already then you can do this to ensure obs1
and obs2
are run in parallel:
obs1.subscribeOn(scheduler).mergeWith(obs2.subscribeOn(scheduler))
...
Depending on what obs2
is doing scheduler
might be Schedulers.computation()
or Schedulers.io()
.
For multiple source observables you can also do this:
Observable.just(obs1, obs2, .. , obsN)
.flatMap(o -> o.subscribeOn(Schedulers.computation())
.ignoreElements()
...
Upvotes: 3