我将提供两个版本的代码片段以便更好地理解:
第一个
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);
此代码的要点是测试
shareReply
如何在refCount
设置为true
的情况下工作。行为是预期的,因为subscription1
observable 发出 5 次,然后我取消订阅,这意味着对于 refCount
test
将再次为 0,是什么导致 test
observable 删除缓存。当我订阅 subscription2
时,发射从 0. 开始
但是如果我使用
fromFetch
运算符,test
observable 的缓存不会被丢弃,即使没有活跃的订阅者来测试 observable:
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
on subscribe 应该重新获取数据,但它是从缓存中获取的。但是缓存应该已经被删除了。我想念什么?
您看到的行为与使用
fromFetch
与 timer
无关,它与源完成与未完成有关。
shareReplay
如果源完成,将为未来的订阅者缓存可观察的源。 (参见这个github问题以供参考)。
share
并指定 resetOnComplete = true
:
share({
connector: () => new ReplaySubject(1),
resetOnComplete : true,
resetOnRefCountZero : true,
})
这里有一个小的StackBlitz你可以玩。