как передать наблюдаемое без создания нового экземпляра - PullRequest
1 голос
/ 24 апреля 2020

Допустим, у меня есть тема, представляющая страницы в разбиваемой на страницы таблице:

pageCount$

Затем я передаю это в новую переменную, которая передается в API для получения данных. для таблицы:

const tableData$ = pageCount$.pipe(switchMap(pageCount => getTableData(pageCount)));

Это прекрасно работает, каждый раз, когда я посылаю новую страницу tableData$ выдает данные для этой страницы.

Теперь здесь возникает проблема и вопрос sh, чтобы решить.

На моей странице я также буду sh, чтобы использовать эти данные таблицы для отображения средних значений того, что они в настоящее время содержат. Поэтому я подумал, что мог бы просто передать tableData$ через карту, которая выполняет эти средние значения.

const averageData$ = tableData$.pipe(map(data => performAverages(data)));

Это работает, но потому что каждый раз, когда я подписываюсь на каждую переменную, это создает новую Например, мой вызов API происходит дважды. Один раз для подписки tableData$ и один раз для подписки averageData$. Однако, я понимаю, что такое поведение разработано специально.

Такое ощущение, что я хочу использовать какой-то оператор tap / fork, но я не думаю, что такой оператор существует.

Возможно ли это вообще? выполнить эти задачи, совершая вызов API только один раз?

Спасибо

Ответы [ 2 ]

1 голос
/ 24 апреля 2020

Для этого можно использовать оператор share.

Сначала создайте наблюдаемое, которое вызывает API, и передайте его с помощью share

https://www.learnrxjs.io/learn-rxjs/operators/multicasting/share.

Тогда результирующая наблюдаемая может быть подписана дважды, обе подписки получат одинаковые результаты, при этом общая наблюдаемая не будет вызываться дважды («многоадресная передача»).

Это должно дать вам кое-что в соответствии с:

const tableData$ = pageCount$.pipe(
    switchMap(pageCount => getTableData(pageCount)),
    tap(_ => console.log('API called')),
    share()
);

// subscribe to tabledata$ twice

tableData$.subscribe(_ => console.log('get and use data once'));
tableData$.subscribe(_ => console.log('get and use data a second time'));

(будет проверено, обратная связь приветствуется!)

1 голос
/ 24 апреля 2020

Что-то вроде этого

const tableData$ = pageCount$.pipe(
   switchMap(pageCount => getTableData(pageCount).pipe(
      map(data => 
         const avg = performAverages(data);
         return {data, avg}
      )
   ))
);

Таким образом, вы получаете объект, содержащий как данные таблицы, так и ее среднее значение, что, как я понимаю, вы ищете.

...