Когда вы используете общий ресурс в httpclient Angular? - PullRequest
1 голос
/ 07 мая 2020

Правильно ли использовать share () в запросе Angular?

public find(params: any): Observable<any> {
    return this.httpClient.get(
      `${environment.apiUrl}/${this.PATH}`,
      {
        params: HttpParamsBuilder.buildQueryParams(params),
      }
    ).pipe(share());
  }

Что лучше использовать, switchMap() или share() в этом случае?

1 Ответ

1 голос
/ 07 мая 2020

TL; DR; Может быть хорошо, в зависимости от ваших намерений. Это, в сочетании с дополнительной работой в коде, вызывающем find, поможет вам избежать одновременных вызовов конечной точки HTTP с одним и тем же параметром.

Так что трудно сказать, есть ли у вас использование оператора share здесь неуместно. Он используется для создания потоков hot при наличии хотя бы одного подписчика. Допустим, у вас есть холодный наблюдаемый поток, излучающий диапазон 1..5, к которому применено share, например:

(Это мраморная диаграмма: ^ = Subscribe,! = Unsubscribe, | = Completed)

Source         ----1----2----3---   ----1----2----3----4----5----|
Subscriber A   ^---1----2----3--!   
Subscriber B                        ^---1----2----3----4----5----|                          
Subscriber C                                    ^-3----4----5----|

Подписчик A подписывается и получает 3 события, после чего отписывается. После этого подписчик B подписывается, и поток начинается с sh. Теперь, когда подписчик C подписывается после 2-го события, он видит только 3..5 - он пропустил первые два события, потому что share ведет многоадресную рассылку и поддерживает поток горячим, пока есть хотя бы один подписчик.

Ваш find метод в том виде, в каком он написан, возвращает поток HTTP, который инициирует вызов для поиска с переданным параметром, когда он подписан, и имеет только одно событие - либо успешный результат, либо ошибку.

Предполагая успешный результат, с несколькими подписчиками вы получите что-то вроде этого (где o - результат).

Source         ---------o|    ---------o|
Subscriber A   ^--------o|
Subscriber B   ------^--o|
Subscriber C                  ^--------o|

Подписчик A делает первую подписку, и пока результат ожидает, подписчик B также подписывается. Они оба получают уведомление об одном и том же результате. Позже подписчик C подписывается, и выполняется новый звонок, и C получает результат fre sh.

Я не могу сказать, хотите ли вы этого. Но чтобы извлечь выгоду из share, это будет означать, что вы кэшируете вызов, чтобы найти где-то определенный параметр c, и повторно его используете. Возможно, вы делаете это, чтобы избежать одновременных одновременных вызовов одного и того же параметра, но не намереваетесь кэшировать результат для использования в будущем. Вам понадобится код для управления повторным использованием наблюдаемого, возвращенного из find.

Вызывающий find() будет каждый раз получать новый наблюдаемый; только если один вызывающий абонент разделяет возвращаемый наблюдаемый объект с несколькими подписчиками, вы получите поведение, описанное выше. Дважды позвоните по номеру find() и подпишитесь на каждую возвращаемую наблюдаемую, каждый подписчик всегда будет запускать отдельный HTTP-вызов.

Если вы намерены фактически кэшировать результаты, вы захотите посмотреть в другом месте такие вещи, как мемоизаторы - примеры мемоизирующие наблюдаемые можно легко найти в Google.

...