RxjS shareReplay : how to reset its value?

后端 未结 4 516
醉梦人生
醉梦人生 2021-01-05 02:30

I use shareReplay to call only once (like a cache) a webservice to retrieve some informations :

In my service :

getProf         


        
相关标签:
4条回答
  • 2021-01-05 02:53

    I know this thread is old, but I think I know what the other answer meant about prepend a "reset" subject to push new values. Check this example:

    private _refreshProfile$ = new BehaviorSubject<void>(undefined);
    
    public profile$: Observable<Customer> = _refreshProfile$
      .pipe(
        switchMapTo(this.callWS()),
        shareReplay(1),
       );
    
    public refreshProfile() {
      this._refreshProfile$.next();
    }
    

    In the above snippet, all profile$ new subscribers will receive the latest emitted value (upon calling callWS() once). If you wish to "refresh" the Customer being shared, you would call "refreshProfile()". This would emit a new value going through switchMapTo, reassigning the replay value and also notifying to any profile$ open subscriber.

    Have a nice one

    0 讨论(0)
  • 2021-01-05 03:00

    Sounds like you can prepend a Subject that will inject the new value with merge:

    private refresh$ = new Subject();
    
    refreshProfile(...): void {
      this.refresh$.next(/* whatever */);
    }
    
    getProfile(): Observable<Customer> {
      return this.callWS().pipe(
        merge(this.refresh$),
        shareReplay(1),
      );
    }
    
    0 讨论(0)
  • 2021-01-05 03:11

    The other answers are all fine, but rather than having to reset the actual shareReplayed observable, a simpler approach might just be caching the result like so:

    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

    0 讨论(0)
  • 2021-01-05 03:14

    Thanks to the answer of martin (which didn't work for me) I found a way to do it :

    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);
        });
    }
    

    I think there is maybe something better/cleaner to do (using a Behavior Subject ?), so if you know something better ..

    0 讨论(0)
提交回复
热议问题