Угловой | Обновлять таблицу каждые 5 секунд с помощью таймера

Я использую таблицу материалов на странице и хочу, чтобы источник данных таблицы обновлялся каждые 5 секунд, чтобы любое изменение значений отражалось в таблице. Вот что я сделал сейчас:

everyFiveSeconds: Observable<number> = timer(0, 5000);

ngOnInit() {
this.everyFiveSeconds.subscribe(() => {
  this.getComponents();
});

getComponents() отправляет запрос на получение и разбивает выходные данные на страницы таблицы материалов. Однако проблема в том, что как только я загружаю эту страницу изначально, запрос на получение выполняется каждые 5 секунд. Но приложение продолжает отправлять запрос, даже если я перехожу на другую страницу. Если я повторно захожу на страницу, запрос отправляется каждые 2,5 секунды, и частота запросов продолжает увеличиваться, если я повторяю его.

Как я могу изменить свой код, чтобы этот запрос на получение отправлялся только тогда, когда я сижу на этой странице компонента, а также убедиться, что при повторном посещении этой страницы не создаются несколько таймеров?


person Inception    schedule 06.05.2020    source источник
comment
Если вы подписались, вы хотите отписаться от него, вы можете отписаться от таймера, наблюдаемого через событие жизненного цикла уничтожения компонента.   -  person penleychan    schedule 06.05.2020
comment
@penleychan: Кажется, это работает. Но я хочу, чтобы вы это проверили. Я добавил this.subscription.unsubscribe() во вновь созданную функцию ngonDestroy. this.subscription — это возвращаемое значение функции subscribe() внутри ngOnInit. Это правильно?   -  person Inception    schedule 06.05.2020


Ответы (2)


Это что-то вроде этого:

import { timer } from 'rxjs';

export class MyClass implements OnInit, OnDestroy {
    subscription: Subscription;
    everyFiveSeconds: Observable<number> = timer(0, 5000);
    
     ngOnInit() {
      this.subscription = this.everyFiveSeconds.subscribe(() => {
         this.getComponents();
       });
     }
    }
    ngOnDestroy() {
      this.subscription.unsubscribe();
    }
}
person vhbazan    schedule 06.05.2020
comment
Спасибо, я понял это точное решение на основе первого ответа, который я получил, но это помогает в качестве проверки. Так что отмечу вопрос решенным. Спасибо! - person Inception; 06.05.2020
comment
импортировать {таймер} из 'rxjs'; связанное определение должно быть импортировано. - person Ahmet Arslan; 01.12.2020

Рекомендуется отказаться от всех ваших подписок на наблюдаемые объекты, которые имеют неопределенное количество выбросов. Никогда не думайте, что фреймворк сделает это за вас. Вы можете сделать это с помощью отказа от подписки, но лично я предпочитаю делать это с помощью оператора Subject вместе с оператором takeUntil. Этот подход особенно полезен, если у вас есть несколько наблюдаемых объектов, от которых нужно отписаться (хотя мне нравится сохранять шаблон во всем коде, поэтому я использую его, даже когда мне нужно позаботиться об одной подписке):

private _destroy$ = new Subject<void>();

ngOnInit() {
  this.everyFiveSeconds
    // You can do this with all of your subscriptions
    // using a single _destroy$ variable
    .pipe(takeUntil(this._destroy$))
    .subscribe(() => {
      this.getComponents();
    });
}

ngOnDestroy() {
  if(this._destroy$ && !this._destroy$.closed) {
    this._destroy$.next();
    this._destroy$.complete();
  }
}
person julianobrasil    schedule 06.05.2020
comment
Я могу понять, насколько это хорошая практика. Однако в моем приложении, за исключением этого единственного случая, когда используется таймер, это всегда простые почтовые запросы, на которые я получаю один ответ только один раз. Не вызовет ли подписка каких-либо проблем? - person Inception; 06.05.2020
comment
Точно нет. - person julianobrasil; 07.05.2020