Как починить автоматическую отписку для Observable в котором используется shareReplay (RXJS@6.5.2)

Контекст: в ангуляре удобно связывать бекенд и сервисы с помощью RXJS стримов. Протягивать стримы до самых вьюх, где вьюха подписывается на стрим (с помощью async pipe) и триггерит всю цепочку вызовов операторов. Преимущество этого подхода в том что вьюха сама отпишется от стрима когда будет “убита” при навигации на другую вьюху.

В RXJS есть оператор shareReplay который я использую когда одни и те же данные с бекенда используются разными компонентами на клиенте. Этот оператор позволяет сделать 1 запрос и переиспользовать его результаты во всех потребителях.

В моем случае есть дашборд который обновляется каждые X секунд (это смоделировано в observable this.refreshInterval), и где данные из 1 API используются в нескольких компонентах.

Код выглядит примерно так:

this.countersDto$ = combineLatest([this.userSelectedDealersSubject, this.refreshInterval]).pipe(
	switchMap(([dealersIds, _]) => {
		return this.dashboardApiService.getCounters({ dealers: dealersIds });
	}),
	shareReplay(1)
);

Проблема
когда пользователь уходит со страницы observalbe this.countersDto$ продолжает слать запросы к бекенду в интервале. Оказывается это известная проблема 1, 2 с оператором shareReplay.

Решение
Чтобы потребители отписались от моего observable нужно передать дополнительный параметр в shareReplay:

this.countersDto$ = combineLatest([this.userSelectedDealersSubject, this.refreshInterval]).pipe(
	switchMap(([dealersIds, _]) => {
		return this.dashboardApiService.getCounters({ dealers: dealersIds });
	}),
	shareReplay({
		bufferSize: 1,
		refCount: true
	})
);
2 лайка