Как debounceTime в OnPu sh Component (stackblitz)? - PullRequest
0 голосов
/ 05 августа 2020

Я изучаю RX JS и имею следующий контекст:

Сервис:

import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable, interval } from 'rxjs';
import { debounceTime, tap, debounce } from 'rxjs/operators';
 
@Injectable({ providedIn: 'root' })
export class SomeProvider {

  private counter: BehaviorSubject<number> = new BehaviorSubject(0);
  public counter$ = this.counter.asObservable() // .pipe(debounceTime(2000))

  constructor(
  ) {
    interval(1000).subscribe(value => {
      console.log(value);
      this.counter.next(value);
    })
  };

}

Компонент:

import { Component, ChangeDetectionStrategy } from '@angular/core';
import { SomeProvider } from './some.service';

@Component({
  selector: 'hello',
  template: `<h1>{{ provider.counter$ | async }}</h1>`,
  styles: [`h1 { font-family: Lato; }`],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class HelloComponent  {

  constructor(public provider: SomeProvider) {

  }
}

Вот stackblitz: https://stackblitz.com/edit/angular-ivy-cdvwnj

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

Вопрос:

  • как правильно применить debounceTime в этом сценарии
  • почему, если мы добавим канал с debounceTime asyn c pipe внутри шаблона перестает работать (и требует дополнительного обнаружения изменений)?

Ответы [ 3 ]

1 голос
/ 05 августа 2020

Вместо того, чтобы переписывать то, что уже написано в docs , давайте попробуем понять простым непрофессиональным языком .

debounceTime () - Это оператор Rx Js, который прослушивает весь входящий поток данных для заданного временного лимита и пересылает только последний .

Пример: -

MyAwesomeObservable().pipe(debounceTime(10000))

Это означает, что debouncetime не будет пересылать поток данных, пока не пройдут 10 секунд. В течение этих 10 секунд, если появится новый поток данных, debounceTime снова начнет ждать 10 секунд.

Your-Case: -

Поскольку interval(1000) передает данные каждые 1 se c, debounceTime(2000) ожидание 2se c никогда не заканчивается.

interval> debouncetime , тогда ваш код будет работать.

1 голос
/ 05 августа 2020

Как и в других упомянутых ответах, поскольку ваш debounceTime выше, чем interval(), это приведет к тому, что все интервальные выбросы будут `` отклонены ''.

Если вы хотите отклонить интервал только для излучения каждые 2 секунды вместо 1 секунды, и вы не можете контролировать интервал времени, вы можете использовать фильтр:

public counter$ = this.counter.asObservable().pipe(
  filter((idx) => !(idx % 2))
)

Это заставит ваш счетчик излучать только при равных выбросах.

см. Здесь

1 голос
/ 05 августа 2020

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

Выдает значение из источника Observable только по прошествии определенного промежутка времени без излучения другого источника .

Это будет работать, если время прошло до debounceTime <время прошло до <code>interval

Демо

...