RxjS shareReplay: как сбросить его значение? - PullRequest
0 голосов
/ 24 января 2019

Я использую 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 только один раз). Я попытался сохранить свое наблюдаемое в переменной и установить его равным нулю, прежде чем повторно инициализировать его, но, похоже, он нарушает подписку компонентов.

Любая помощь?

Спасибо

Ответы [ 4 ]

0 голосов
/ 07 августа 2019

Все остальные ответы хороши, но вместо того, чтобы сбрасывать фактическую наблюдаемую 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

0 голосов
/ 25 января 2019

Благодаря ответу Мартина (который у меня не работал) я нашел способ сделать это:

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

Я думаю, что, может быть, есть что-то лучше / чище (использование предмета поведения?), Так что если вы знаете что-то лучше ..

0 голосов
/ 08 мая 2019

Я знаю, что эта ветка старая, но я думаю, что знаю, что имел в виду другой ответ о добавлении предмета "сброса" для добавления новых значений. Проверьте этот пример:

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$ открытого подписчика.

Хорошего вам

0 голосов
/ 24 января 2019

Звучит так, как будто вы можете добавить субъекта, который будет вводить новое значение, с помощью merge:

private refresh$ = new Subject();

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

getProfile(): Observable<Customer> {
  return this.callWS().pipe(
    merge(this.refresh$),
    shareReplay(1),
  );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...