Rxjs shareReplay无效(超时)

时间:2020-01-15 13:39:52

标签: rxjs

在Rxjs中,想象一个流将获取一些数据,然后使用shareReplay来保存最新值以进行优化。

const value = fetchData().pipe(
  shareReplay(1)
)

但是,如果该值在这种情况下(仅在这种情况下)可以到期,应该重新获取。

const value = fetchData().pipe(
  shareReplay(1),
  switchMap((value) => isExpired(value) ? fetchData() : of(value))
)

这不太正确,因为在第一次重新获取后,该值不再共享,并且每次都会重新获取。

如何在Rxjs中表达“保持最新值”和“无效”的功能?

2 个答案:

答案 0 :(得分:1)

您可以执行以下操作:

const value$ = fetchData().pipe(
  expand(res => timer(res.validForMs).pipe(switchMap(() => fetchData()))),
  shareReplay(1)
);

通过这种方式,缓存失效发生在shareReplay之前,并且每个订阅者还将获得最新的值。

我已经做了一个简单的例子来演示:

//  just mocks
// ---------------------------
const fetchData = () =>
  of({
    token: uuid(),
    validForMs: 2000
  });
// ---------------------------

const value$ = fetchData().pipe(
  expand(res => timer(res.validForMs).pipe(switchMap(() => fetchData()))),
  shareReplay(1)
);

merge(
  value$.pipe(
    tap(res => console.log(`Subscriber 1 received token ${res.token}`))
  ),
  value$.pipe(
    tap(res => console.log(`Subscriber 2 received token ${res.token}`))
  ),
  value$.pipe(
    tap(res => console.log(`Subscriber 3 received token ${res.token}`))
  )
).subscribe();

输出为:

Subscriber 1 received token f7facb6f-2c16-4b0f-abc7-53e5c7461778
Subscriber 2 received token f7facb6f-2c16-4b0f-abc7-53e5c7461778
Subscriber 3 received token f7facb6f-2c16-4b0f-abc7-53e5c7461778

Subscriber 1 received token 67419f6a-65ff-482d-9ede-c38b1405e31e
Subscriber 2 received token 67419f6a-65ff-482d-9ede-c38b1405e31e
Subscriber 3 received token 67419f6a-65ff-482d-9ede-c38b1405e31e

Subscriber 1 received token b978b439-3ae5-440e-9d96-9f320db6e051
Subscriber 2 received token b978b439-3ae5-440e-9d96-9f320db6e051
Subscriber 3 received token b978b439-3ae5-440e-9d96-9f320db6e051

此处https://stackblitz.com/edit/rxjs-kqybmd

演示

答案 1 :(得分:0)

好吧,只需保留一个变量即可:const val = fetchData().pipe(shareReplay(1)); 然后: val.pipe(switchMap((value) => isExpired(value) ? val : of(value)))