如何在 OnPush 组件(stackblitz)中去抖时间?

How to debounceTime in OnPush Component (stackblitz)?

我正在学习 RXJS 并且有以下背景:

服务:

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 去抖动它。我认为这就像使用 debounceTime 运算符向 Observable 添加管道一样简单。但是,如果我取消注释该更改 - 计数器甚至不存在。

问题:

来自documentation

Emits a value from the source Observable only after a particular time span has passed without another source emission.

如果传递给 debounceTime 的时间 <传递给 interval

的时间,这将起作用

Demo

与其重写 docs 中已写的内容,不如尝试用简单的 外行语言.

来理解

debounceTime() - 这是一个 RxJs 运算符,它监听所有传入的 data-stream for a given time-limit 并且只转发 最后一个 .

示例:-

MyAwesomeObservable().pipe(debounceTime(10000))

这意味着 debouncetime 不会转发 data-stream 直到 10 秒过去。在那 10 秒内,如果有新的 data-stream 出现,debounceTime 将再次开始等待 10 秒。

Your-Case :-

由于 interval(1000) 每 1 秒传递一次数据,debounceTime(2000) 2 秒的等待永远不会结束。

interval > debouncetime,你的代码将起作用。

像提到的其他答案一样,因为你的debounceTime高于interval(),它会导致所有间隔排放量为'debounced'。

如果你想去抖一个间隔只每 2 秒发出一次,而不是 1 秒,并且你无法控制间隔时间,你可以使用过滤器:

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

这将使您的计数器仅在均匀发射时发射。

see here