1

Assume this Angular code:

import { Component } from '@angular/core';
import { shareReplay, tap, timer } from 'rxjs';

@Component({
  selector: 'my-app',
  template: '{{test$ | async}} {{test$ | async}}',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  test$ = timer(0, 1000).pipe(
    shareReplay({ bufferSize: 1, refCount: true }),
    tap(console.log)
  );
}

Why does console.log appear twice and the subscription is apparently not shared? To my knowledge, the overload with config param for shareReplay is the current recommended way to be explicit about sharing subscriptions. Am I getting something wrong?

rxjs 7.5.2, ng 13.2

user776686
  • 7,933
  • 14
  • 71
  • 124

2 Answers2

1

shareReplay accomplish the share by creating an intermediate subject.

Thus, obs = source -> opratorA -> opB -> share(intermediate subjectC) -> opD -> opE

When you subscribe to obs, you actually subscribe to subjectC, with opD and opE.
Thus, the stream after opA and opB is shared, the calculation of opD and opE is not shared.

const test$ = timer(0, 1000).pipe(
    map(v => v * 2), // shared
    tap(console.log), // shared
    shareReplay({ bufferSize: 1, refCount: true }),
    tap(console.log) // not shared
  );
user5474476
  • 141
  • 9
0

Because you are actually subscribing to it twice in your code

template: '{{test$ | async}} {{test$ | async}}'

If you move the tap above shareReplay it should appear once

Fan Cheung
  • 10,745
  • 3
  • 17
  • 39