Наговнокодил "в лоб" такую фигню:
function heavyRequest() {
console.log('heavyRequest triggered');
// здесь какой-то накладный запрос
return timer(1000);
}
let subject$ = new Subject();
let pending = false;
let observable$ = subject$.pipe(
tap(() => pending = true),
switchMap((value) => {
// вызывается только один раз для каждого значения,
// независимо от количества подписчиков
return heavyRequest().pipe(mapTo(value))
}),
tap(() => pending = false),
shareReplay(1),
filter(() => !pending)
);
// 'first', затем 'second'
observable$.subscribe((v) => console.log('subscribe 1', v));
subject$.next('first');
setTimeout(() => {
// 'first' сразу, затем 'second'
observable$.subscribe((v) => console.log('subscribe 2', v));
}, 2000);
setTimeout(() => {
subject$.next('second');
// только 'second'
observable$.subscribe((v) => console.log('subscribe 3', v));
}, 3000);
// Итоговый лог:
// "heavyRequest triggered"
// "subscribe 1" "first"
// "subscribe 2" "first"
// "heavyRequest triggered"
// "subscribe 1" "second"
// "subscribe 2" "second"
// "subscribe 3" "second"
Вопрос в том, как это сделать правильно по фенщую. Мозг уже плавится, но сильно подозреваю что всё должно быть намного проще.