Reputation: 67
I am trying to understand the following code's console output. I was expecting it will console log 0 through 9 every 500ms and then start over with 0 again (and end up with 9).
But the fact is it would only console log 0-9 the very first time, and then the output became 0 - 8, with a 1 second pause on 8, and then start with 0 again.
My question is
Since the source observable emits every 5 secs and inner observable emits every 500ms, it should have enough time for the inner observable to emit 0 to 9, and it should not pause on 8.
Here is the same code on stackblitz: https://stackblitz.com/edit/typescript-eb62ap?file=index.ts&devtoolsheight=100
// RxJS v6+
import { timer, interval } from 'rxjs';
import { switchMap } from 'rxjs/operators';
//emit immediately, then every 5s
const source = timer(0, 5000);
//switch to new inner observable when source emits, emit items that are emitted
const example = source.pipe(switchMap(() => interval(500)));
//output: 0,1,2,3,4,5,6,7,8,9...0,1,2,3,4,5,6,7,8
const subscribe = example.subscribe(val => console.log(val));
Upvotes: 0
Views: 238
Reputation: 5764
Why 9 only showed up once?
In my case 9 is not shown at all. So I guess it could be some kind of time inaccuracy? This is tight - theoretically interval
starts little bit later than timer. Therefore it prints only 9 values (0-8).
Why there's a 1 second (instead of 500ms) pause on 8?
The 8 is printed at 4500ms. When timer reaches 5000ms (which takes 500ms since 8) it spins up the new interval
. The new interval will emit after another 500ms. Therefore 1s delay between these.
If there's 9 printed I would expect delay to be only 500ms. But again - in my case 9 is never printed.
Upvotes: 1
Reputation: 828
Because timer is not that accurate, that's the problem of NodeJS event loop and timer API.
the last interval which will print 9
is about to execute but timer(0, 5000)
has reached its time.
You could try increase timer
just a little bit to let the 9
printed out
const source = timer(0, 5100); //add some time
const example = source.pipe(switchMap(() => interval(0,500)));
or use timer
instead of interval
so that it will execute without delay to see the 9
is printed
const source = timer(0, 5000);
const example = source.pipe(switchMap(() => timer(0,500))); //use timer
Upvotes: 2