Reputation: 1496
Currently trying to get my head around this:
import {Observable} from "rxjs";
import {delay, first, takeUntil, tap, withLatestFrom} from "rxjs/operators";
const obs1 = new Observable(s => s.next(1)).pipe(delay(1000));
const obs2 = new Observable(s => s.next(2));
obs2
.pipe(
withLatestFrom(obs1),
tap(() => console.log('tap'))
)
.subscribe(() => console.log('subscribe'));
"subscribe" (and hence "tap") is never logged. But why?
If I remove the delay
from the first Observable everything works. If I change to combineLatest([obs1, obs2])
everything works fine.
This is the reproduction of a bug where 2 HTTP requests are sent. If the request within withLatestFrom
took too long the subscribe
did never happen. With combineLatest
everything works as expected (which means the subscribe
happens after both requests are done).
If combineLatest
fixes my bug I'm fine with that - but I'd like to understand why.
Upvotes: 2
Views: 1258
Reputation: 54771
The documentation says:
https://rxjs.dev/api/operators/withLatestFrom
All input Observables must emit at least one value before the output Observable will emit a value.
That is because withLatestFrom()
is a non-blocking operator.
obs2
emits the first value, and then withLatestFrom()
will emit with the latest value from obs1
, but there is no latest value so nothing is emitted.
If obs2
emitted a second value later after obs1
then a value would be emitted.
If combineLatest fixes my bug I'm fine with that - but I'd like to understand why.
combineLatest()
works differently, because it emits after all observables emit a value.
Upvotes: 3