RxjS shareReplay:如何重置其值?

时间:2019-01-24 14:01:36

标签: typescript asynchronous caching rxjs reactive-programming

我使用shareReplay仅调用一次 (如缓存)网络服务来检索一些信息:

为我服务:

getProfile(): Observable<Customer> {
    return this.callWS().pipe(shareReplay(1));
}

在多个组件中:

this.myService.getProfile().subscribe(customer => {
    console.log('customer informations has been retrieved from WS :', customer);
});

现在,我想添加一种方法来强制刷新信息(仅绕过一次shareReplay)。我尝试将observable存储在一个变量中,然后在将其初始化之前将其设置为null,但这似乎破坏了组件的订阅。

有帮助吗?

谢谢

4 个答案:

答案 0 :(得分:1)

听起来像您可以添加一个主题,该主题将使用merge注入新值:

private refresh$ = new Subject();

refreshProfile(...): void {
  this.refresh$.next(/* whatever */);
}

getProfile(): Observable<Customer> {
  return this.callWS().pipe(
    merge(this.refresh$),
    shareReplay(1),
  );
}

答案 1 :(得分:1)

我知道此线程很旧,但是我想我知道其他答案的意思是在“重置”主题之前添加新值。检查此示例:

private _refreshProfile$ = new BehaviorSubject<void>(undefined);

public profile$: Observable<Customer> = _refreshProfile$
  .pipe(
    switchMapTo(this.callWS()),
    shareReplay(1),
   );

public refreshProfile() {
  this._refreshProfile$.next();
}

在上面的代码段中,所有profile$个新订阅者都将收到最新发出的值(一次调用callWS()时)。如果您希望“刷新”要共享的客户,则可以调用“ refreshProfile()”。这将发出一个通过switchMapTo的新值,重新分配重播值,并通知任何profile$打开的订户。

有一个不错的人

答案 2 :(得分:1)

其他答案都很好,但是不必重置实际的shareReplayed观察值,一种更简单的方法可能只是将结果缓存如下:

protected profile$: Observable<Customer>;

getProfile$(): Observable<Customer> {
  if (!this.profile$) {
    this.profile$ = this.callWS().pipe(shareReplay(1));
  }

  return this.profile$;
}

resetProfile() {
  this.profile$ = null;
}

ref:https://blog.angularindepth.com/fastest-way-to-cache-for-lazy-developers-angular-with-rxjs-444a198ed6a6

答案 3 :(得分:0)

感谢马丁的回答(这对我不起作用),我找到了一种方法:

protected profile: Observable<Customer>;
private refresh$ = new Subject<Customer>();

constructor() {
    this.profile = this.refresh$.pipe(shareReplay(1));

    this.resetProfile();
}


getProfile(): Observable<Customer> {
    return this.profile;
}

resetProfile() {
    this.callWS().subscribe(user => {
        this.refresh$.next(user);
    });
}

我认为可能有更好/更清洁的方法(使用行为主题?),所以,如果您知道更好的方法..