为了更好地理解,我将提供两个版本的代码片段:
1日1
const test = timer(0, 1000).pipe(shareReplay({ bufferSize: 1, refCount: true }));
const subscription1 = test.subscribe(
(value) => console.log('Subscription 1:', value),
(error) => console.error(error),
() => console.log('Subscription 1 completed'),
);
setTimeout(() => {
subscription1.unsubscribe();
}, 6000);
setTimeout(() => {
const subscription2 = test.subscribe(
(value) => console.log('Subscription 2:', value),
(error) => console.error(error),
() => console.log('Subscription 2 completed'),
);
}, 10000);
这段代码的主要目的是测试当refCount
设置为true
时shareReply
如何工作。行为是预期的,因为subscription1
可观察对象发出5次,然后我取消订阅,这意味着refCount
将再次为test
为0,这导致test
可观察对象丢弃缓存。当我订阅subscription2
时,排放量从0开始。
但是如果我使用fromFetch
操作符,test
的缓存不会被丢弃,即使没有活跃的订阅者来测试可观察对象:
export const groupsRaw$ = fromFetch('/some_endpoint').pipe(
shareReplay({ bufferSize: 1, refCount: true }),
);
const subscription1 = groupsRaw$.subscribe(
(value) => console.log('Subscription 1:', value),
(error) => console.error(error),
() => console.log('Subscription 1 completed'),
);
setTimeout(() => {
subscription1.unsubscribe();
}, 6000);
setTimeout(() => {
const subscription2 = groupsRaw$.subscribe(
(value) => console.log('Subscription 2:', value),
(error) => console.error(error),
() => console.log('Subscription 2 completed'),
);
}, 10000);
网络选项卡中只有一个请求。
我期望订阅上的subscription2
应该重新获取数据,但它从缓存中获取数据。但是缓存应该已经被删除了。我错过了什么?
你所看到的行为与使用fromFetch
和timer
无关,它与源完成和未完成有关。
shareReplay
将缓存源可观察对象,如果它的源完成,供未来的订阅者使用。(参考见github issue)。
要实现您想要的行为,您可以使用share
并指定resetOnComplete = true
:
share({
connector: () => new ReplaySubject(1),
resetOnComplete : true,
resetOnRefCountZero : true,
})
这里有一个小的StackBlitz你可以玩一下。
自从所有的"重置"选项默认为true
,实际上不需要指定它们。所以你可以简单地输入:
share({ connector: () => new ReplaySubject(1) })