Как убедиться, что HTTP-запрос вызывается только один раз?

У меня есть серверная служба, которая возвращает данные пользователя, которые мне нужны для нескольких компонентов Angular. Моя проблема в том, что он явно вызывался несколько раз. Вот мой запрос на получение:

getUser(): Observable<User> {
  if (this.user) {
    return Observable.of(this.user);
  } else {
    return this.http
      .get<User>(BACKENDPATH)
      .map((user: User) => new User().deserialise(user))
      .do((user) => {
        this.user = user;
        console.info(this.user.getUserName());
        return this.user;
      });
   }
}

Я пробовал следующие методы после получения части функции, но ни один из них не работал:

  • .publishReplay (1) .refCount ()
  • .shareReplay ()
  • .shareReplay (1)

Эти методы сработали для других в Интернете, поэтому я предполагаю, что я делаю что-то не так с их реализацией, но я не могу понять, что именно.

Я предполагаю, что запрос отправляется много раз, потому что, прежде чем попасть в строку this.user = user;, многие компоненты вызвали метод getUser(). Можешь подтвердить?

Picci 06.07.2018 11:52

@Picci Да, именно поэтому, но я считаю, что одна из целей опубликованных мной методов состоит в том, чтобы они не отправляли запрос на получение несколько раз

Shane Watson 06.07.2018 12:02

Ответ на ваш вопрос находится здесь: stackoverflow.com/questions/51044291/…

siva636 06.07.2018 12:05

@ShaneWatson Вопрос в том, как вы используете getUser(). Вы звоните несколько раз? Или вы делаете один звонок, а затем звоните subscribe() несколько раз?

martin 06.07.2018 12:06
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
1
4
269
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы создаете новый поток с каждым вызовом getUser(). Решение: сделайте один запрос Http и работайте с кэшированными / сохраненными данными. Используйте подход ниже

export class SharedService {

    data$: Observable<User>;
    getUser(): void {

        this.data$ = this.http
            .get<User>(BACKENDPATH)
            .map((user: User) => new User().deserialise(user))
            .do((user) => {
                this.user = user;
                console.info(this.user.getUserName());
                return this.user;
            }).shareReplay(1);
    }

    getData(): Observable<User> {
        return this.data$;
    }
}

Составная часть:

this.service.getData().sub(...)

Викас помог разобраться в этой проблеме. Теперь это мой код:

userData: Observable<User> = this.http
  .get<User>(BACKENDPATH)
  .map((user: User) => new User().deserialise(user))
  .shareReplay(1);

getUser(): Observable<User> {
  return this.userData;
}

Если вы собираетесь вызывать свой метод несколько раз, вы в конечном итоге создаете новый поток с каждым вызовом, т.е. будет запускаться несколько запросов. Лучше сделать один запрос и работать с кэшированными данными.

Vikas 06.07.2018 12:19

Привет, @Vikas, теперь я понимаю и обновил комментарии, это работает. Как вы думаете?

Shane Watson 06.07.2018 15:02

Другие вопросы по теме