Angular: Должен ли я подписываться () на http.get () каждый раз, когда мне нужно обновить? - PullRequest
0 голосов
/ 07 сентября 2018

Интересно, использую ли я Observable.subscribe () слишком много раз или нет.

В моем классе компонентов у меня есть функция loadData (). Он вызывает другую функцию this.service.getData (), которая использует HttpClient.get () для выполнения HTTP-запроса к серверу.

В настоящее время в моей функции loadData () я подписываюсь на результат this.service.getData ().

Каждый раз, когда пользователь нажимает кнопку «Обновить», я хотел бы вызывать свою функцию loadData ().

Вопрос

  • Если я буду вызывать свою функцию loadData () каждый раз, когда мне нужно будет выполнить HTTP-запрос, я создам столько подписчиков?
  • Есть ли риск утечки памяти?
  • Если так, знаете ли вы, как я должен рефакторинг своего кода?

Ответ

Образцы кода

private loadData() {
    this.loading = true;
     const subscription = this.service.getData()
      .pipe(
  // console.log() with a delay added for test - START
  map(val => {
    window.setTimeout(() => {
      // This will print true.
      console.log('After delay: Is Subscriber closed?', subscription.closed);
    }, 10);
    return val;
  }),
    // console.log() with a delay added for test - END
    takeUntil(this.ngUnsubscribe))
      .subscribe(data => {
        this.data = data;
        // This will print false.
        console.log('Is Subscriber closed?', subscription.closed);
      },
      error => {
        console.error(error);
        throw error;
      },
      () => {
        this.loading = false;
      });
}
getData(): Observable<DataObject> {
    const uri = encodeURI(this.configService.getUri());
    const headers = new HttpHeaders();
    if (this.pipelineEtag) {
      headers.set('If-None-Match', this.pipelineEtag);
    }
    return this.http.get(uri, {
      headers: headers,
      observe: 'response'
    }).pipe(
      map(resp => this.processResponse(resp)),
      catchError(error => this.handleError(error, this.envProduction))
    );
}

Ответы [ 3 ]

0 голосов
/ 07 сентября 2018

каждый раз, когда HTTP-вызов возвращает значение, Observable завершается. так что безопасно делать что-то подобное в Сервисе

loadData() { 

    return this.http.get<Data>(dataUrl).pipe(
      //  tap(data => console.log(data)), // eyeball results in the console
      catchError(err => this.handleError(err))
    );

}

, а затем позвоните

this.service.loadData().subscribe((data:Data) => do somthing)

вы можете даже вызвать выхлопные карты или switchMap для управления наблюдаемым потоком, чтобы не слишком много «подсказывать» серверу

0 голосов
/ 07 сентября 2018

Итак, в конце концов

0 голосов
/ 07 сентября 2018

Это правильное использование, и нет риска создать несколько подписчиков.

Из документации:

AsyncPipe автоматически подписывается (и отписывается) за вас.

Источник


Техническая деталь заключается в том, что после завершения запроса Http вызывается метод .complete наблюдаемой, который убивает всех текущих подписчиков. Это означает, что ваши подписчики создаются, используются и немедленно удаляются.

...