Reputation: 17762
I have 2 different Observables, let's call them racer_1 and racer2, which emit when 2 different events occur.
If racer_1 occurs I have to perform the logic of function doStuff_1(), if racer_2 occurs I have to perform doStuff_2().
racer_1 and racer_2 are not mutually exclusive and they can occur one after the other, but what I want to achieve is that if any of them occur, I process just that one with its associated function.
It seems clearly the case of using the race
function of RxJs.
race(
racer_1.pipe(
tap(() => doStuff_1()),
finalize(() => console.log('racer 1 completed'))
),
racer_2.pipe(
tap(() => doStuff_2()),
finalize(() => console.log('racer 2 completed'))
)
)
Unfortunately though it may happen that racer_1 emits first at t0 and doStuff_1() starts a synchronous execution which ends at t0+1000.
In the meantime, at t0+200 racer_2 emits and the execution of doStuff_2() is much shorter so that it ends at t0+300.
In this case what I see is that racer_2 "wins the race" and its emissions continue to get processed, while racer_1 gets completed.
On the contrary what I would like to see is that racer_1 wins since it occurred first, even if its processing can get long to be completed.
Is there a way to obtain such behavior?
Upvotes: 1
Views: 490
Reputation: 96889
You can just reorder operators and wrap the initial emissions from both source Observables and perform doStuff_1
or doStuff_2
later:
race( // wrap emissions with tmp objects
racer_1.pipe(map(result => { type: 'racer1', result })),
racer_2.pipe(map(result => { type: 'racer2', result })),
)
.tap(({ type, result }) => type === 'racer1'
? doStuff_1()
: doStuff_2()
)
map(({ type, result }) => result) // unwrap the object
Upvotes: 1