我有一个外部热资源在观察者可以订阅之前推送值。订阅后,已故的观察者应该收到最新的值以及此后的每个值。为此,我使用了以下代码(相关行标记为“ <<<”,此处的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
与第二种方法相当,实际上是通过这种方法实现的。我想念什么?
答案 0 :(得分:2)
使用s.pipe(shareReplay(1))
时,您只是在链中添加了一个运算符(例如更改链的原型)。但是没有订阅,并且shareReplay
本身没有任何观察者时也没有订阅其源。因此,它不缓存任何内容,因为即使源“热”也没有订阅源Observable。
但是,当您使用s.subscribe(r)
时,您通常会订阅s
,因此r
开始接收项目,ReplaySubject
将对其进行缓存。