as per the definition of the switchMap
On each emission the previous inner observable (the result of the function you supplied) is cancelled and the new observable is subscribed. You can remember this by the phrase switch to a new observable.
now, i have a code like this
const source = timer(0, 5000).pipe(map(x=>`${x}`));
const example = source.pipe(switchMap((f) => interval(1000).pipe(map(y=>`f${f}-s${y}`))),take(20));
const subscribe = example.subscribe(val => console.log(val+' '+ new Date().getSeconds()));
and the result is this
my question is,
25th second - the outer function is called and the inner function is not yet triggered, so the latest value of the outer function is 0 and inner function is also 0 as a default one because it has no value yet f0-s0 25
26th second - the inner function is called and the value ideally should be 0 as the function is just called first time but it is 1 ie. f0-s1 26
30th second - the outer function is called which resets the inner function value to 0, ie. f1-s0 30
why is the inner function got reset on the 35th second, it is still 1 second remaining
stackblitz link
i find it very difficult to understand the concept, thank you
This is because RxJS by default for async actions uses setTimeout
and setInterval
function that don't guarantee they'll make exactly the timeout you want.
So if you use timeouts 5000
and 1000
then it's not guaranteed which of the actions will happen first after 5s. Sometimes the outer Observable emits first and sometimes the inner emits first but switchMap
can't do anything about it.
You can see how different the times can get with eg. this:
const start = new Date().getTime();
setInterval(() => console.log(new Date().getTime() - start), 1000);
Live demo: https://stackblitz.com/edit/typescript-urep5j
1004
2001
3002
4000
4998
...
So sometimes the delay is 1004
and other times just 998
.
I think, you're wrongly assuming that your source started emitting at 25s
second, while it started at 24s
. And theres no "default 0".
Source emits at t0
, then in 1s
inner interval
will emit. Inner interval
will have 5 seconds to emit 4 or 5 times, before you'll switch to another value from the source timer
. If your source timer
started emitting at 24s
, then first value you'll get on the subscription is at 25s
— when the interval
will emit its first value.
The reason for 4 or 5 time is in RxJS and JS scheduling. See this stackblitz for a rough example of what might be going on. Explaining this in detail would take more research effort and time.
Heres a marble diagram picturing mergeMap vs exhaustMap vs switchMap vs concatMap
behavior to get a better understanding:
Check this mergeMap vs exhaustMap vs switchMap vs concatMap playground.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With