Rx js как кэшировать результат наблюдаемого для данного аргумента? - PullRequest
0 голосов
/ 14 марта 2020

В моем приложении я использую rx js, и у меня есть метод, который выглядит следующим образом:

query<T extends TableRow>(queryString: string, silent = false): Observable<T[]> {
  return this.sqliteService.dbQuery<T>(queryString).pipe(
    tap(val => {
      if (this.configService.debugMode && !silent) {
        console.log(`\n${queryString}`);
        console.log(val);
      }
    })
  );
}

Мой query метод вызывает между собой dbQuery, который запрашивает базу данных sqlite.

Кроме того, метод query вызывается в моем приложении много раз. Поэтому я хотел бы глобально кэшировать результат всякий раз, когда queryString одинаков.

Другими словами, мне бы хотелось, чтобы метод query не вызывал снова dbQuery при вызове с * Параметр 1014 *, который был вызван ранее путем возврата ранее кэшированного значения.

Не уверен, что это уместно: мой метод query находится в одноэлементной службе Angular.

Ответы [ 2 ]

0 голосов
/ 15 марта 2020

Я получил следующее решение:

private cache: Observable<string>[] = [];

getItem(id: number): Observable<string> {

  if (!this.cache[id]) {
    this.cache[id] = this.query<string>(
      `SELECT column FROM table WHERE id = ${id}`
    ).pipe(shareReplay());
  }

  return this.cache[id];
}
0 голосов
/ 14 марта 2020

В первый раз сохраните удаленное значение в свойстве локального кэша с ключом, который является строкой запроса.

При последующих запросах верните существующее свойство для соответствующего ключа.

private cache = {};

query<T extends TableRow>(queryString: string, silent = false): Observable<T[]> {
  if (this.cache.hasOwnProperty(queryString)) {
    return of(this.cache[queryString]);
  }

  return this.sqliteService.dbQuery<T>(queryString).pipe(
    tap(val => {
      this.cache[queryString] = val;

      if (this.configService.debugMode && !silent) {
        console.log(`\n${queryString}`);
        console.log(val);
      }
    })
  );
}
...