user776686
user776686

Reputation: 8655

shareReplay(config) does not seem to share subscription

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

Upvotes: 1

Views: 600

Answers (2)

user5474476
user5474476

Reputation: 141

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
  );

Upvotes: 1

Fan Cheung
Fan Cheung

Reputation: 11345

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

Upvotes: 0

Related Questions