shareReplay与ReplaySubject-仅ReplaySubject在订阅之前缓存最新值

时间:2019-01-04 20:59:45

标签: rxjs rxjs6

我有一个外部热资源在观察者可以订阅之前推送值。订阅后,已故的观察者应该收到最新的值以及此后的每个值。为此,我使用了以下代码(相关行标记为“ <<<”,此处的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与第二种方法相当,实际上是通过这种方法实现的。我想念什么?

1 个答案:

答案 0 :(得分:2)

使用s.pipe(shareReplay(1))时,您只是在链中添加了一个运算符(例如更改链的原型)。但是没有订阅,并且shareReplay本身没有任何观察者时也没有订阅其源。因此,它不缓存任何内容,因为即使源“热”也没有订阅源Observable。

但是,当您使用s.subscribe(r)时,您通常会订阅s,因此r开始接收项目,ReplaySubject将对其进行缓存。