Why does the second switchMap execute hundreds of times on subscribe?

Viewed 65

Here is the minimal code that reproduces the problem:

import { defer, BehaviorSubject, of } from "rxjs";
import { shareReplay, switchMap } from "rxjs/operators";

const oneRandomNumber = defer(() => of(Math.floor(Math.random() * 20)));

const cache = { key: oneRandomNumber.pipe(shareReplay(1)) };

export const swr = () =>
  new BehaviorSubject(null).pipe(
    switchMap(() => cache.key),
    switchMap(number => {
      console.log(number); // WHY DOES THIS EXECUTE SO MANY TIMES?!
      return cache.key;
    })
  );

swr().subscribe();

demo

I would expect to only see one number logged. Not hundreds.

The problem disappears if you do any of the following things:

  • remove shareReplay(1)
  • you don't use the cache object, but just use oneRandomNumber.pipe(shareReplay(1)) directly
  • don't use switchMap twice

But my eventual code needs all of those things.

1 Answers

Your code seems work as expected. In this code you replay observable each time it used, - it's what shareReplay exactly do. And with your two switchMap operators it goes to infinity replaying job and falls to hell, because of each other.

Reason for that - your first switchMap operator doesn't have endpoint, like take(1) or something in that kind.

If you though buffer size do any job here, it's wrong. Buffer works only on multiple subscriptions, not multiple observable usage in that case.

Related