Кэширование нескольких API с помощью RxJS в Angular

У меня есть компонент с несколькими вкладками, по которым пользователи могут перемещаться вперед и назад. Мне нужно загрузить данные из серверной части на первой вкладке. Это создает ненужные HTTP-вызовы каждый раз при повторной инициализации компонента 1. Моя идея состоит в том, чтобы создать службу кэширования, в которой я бы сохранял результат HTTP-вызова, и при повторной инициализации компонента он получал данные из службы (а не из бэкэнда).

Вот еще несколько требований:

  • Сервис должен быть предоставлен в родительском компоненте (когда компонент уничтожается, сервис и кэшированный результат также должны быть уничтожены).
  • Первый HTTP-вызов должен быть инициирован при инициализации компонента 1, а не при инициализации службы.

Каким-то образом это начинает работать, пока я не добавляю Тему для запуска первой загрузки. Теперь он запускает HTTP-вызов каждый раз, когда компонент 1 повторно инициализируется. Демо-версия Stackblitz

Любая помощь приветствуется! Спасибо

🤔 А знаете ли вы, что...
С помощью Angular можно создавать анимации и переходы между элементами интерфейса.


65
2

Ответы:

Самая простая система «кэширования», которую я когда-либо видел, — это хранение данных в переменных.

data!:any[]
getData()
{
   if (this.data)
      return of(data)

   return this.httpClient.get(...).pipe(
      tap((res:any[])=>this.data=res))
}

Решено

Причина ваш код извлекается каждый раз, когда вы загружаете Компонент А, заключается в том, что вы вызываете triggerLoad$.next() каждый раз, когда инициализируется Компонент А!

На самом деле вам не нужен отдельный триггер, вы можете просто объявить один наблюдаемый объект codetables$, который одновременно извлекает и кэширует данные.

  readonly codetables$ = from(this.codetableTypes).pipe(
    mergeMap(codetableType => this.getCodetable(codetableType)),
    scan((acc, current) => ({...acc, ...current}), {} as CodetableOptions),
    shareReplay(1),
    takeUntilDestroyed()
  );

Здесь мы используем shareReplay для кэширования значения. Он ведет себя как ReplaySubject(1); когда потребители подписываются, они немедленно получают самую последнюю информацию.

Вот рабочий Stackblitz