У меня есть внешний горячий источник, передающий значения, прежде чем наблюдатели смогут подписаться. После подписки, опоздавшие наблюдатели должны получить последнее значение и каждое значение с этого момента. Для этого я использовал следующий код (соответствующая строка помечена '<<<', <code>s Subject
здесь только для того, чтобы можно было создать простейший из возможных примеров, в действительности горячий источник работает по-другому):
// irrelevant, just to send values
const s = new Subject();
// make the observable cache the last value
const o = s.pipe(shareReplay(1)); // <<<
// now, before subscription, values start coming in
s.next(1);
s.next(2);
s.next(3);
o.subscribe(n => console.warn('!!!', n));
Это не работает (я ожидал, что он напечатает !!! 3
, но ничего не происходит), но я нашел способ заставить его работать:
// irrelevant, just to send values
const s = new Subject();
const r = new ReplaySubject(1);
s.subscribe(r);
const o = r.asObservable();
s.next(1);
s.next(2);
s.next(3);
o.subscribe(n => console.warn('!!!', n));
т.е. вместо использования shareReplay(1)
, я создаю ReplaySubject(1)
и использую его как мост. С этим кодом я получаю желанный !!! 3
.
Хотя я счастлив, что это работает, я хотел бы понять, почему первый фрагмент не работает. Я всегда думал, что shareReplay
в значительной степени эквивалентен второму способу и фактически реализован таким образом. Чего мне не хватает?