首页 > 解决方案 > 一定时间后重置扫描累加器 RxJS

问题描述

我有一个 fromEvent 附加到输入 keydown 事件。这样我就可以收听 KeyEvents。

在管道内部,我使用了扫描操作符,因此我可以累积用户最近引入的 3 个密钥。

我检查了扫描,累加器长度,所以如果它已经是三个,我清理它(手动重置)。

我需要一种方法,当用户输入时,在接下来的 3000 毫秒内,他可以继续输入直到达到限制(3 个键)但如果用户慢于时间限制(3 秒),下次他输入时,我会手动复位蓄能器。

  fromEvent(myInput.nativeElement, 'keydown').pipe(
    tap(e => e.preventDefault()),
    scan((acc: KeyboardEvent[], val: KeyboardEvent) => {
      // Add condition here to manually reset the accumulator...
      if (acc.length === 3) {
        acc = [];
      }
      return [...acc, val];
    }, []),
    takeUntil(this.destroy$)
  ).subscribe((events: KeyboardEvent[]) => console.log(events));

我试图以某种方式将它与计时器合并,但我不知道如何。不知道如何到达那里。

标签: rxjsrxjs-pipeable-operators

解决方案


您可以在timeInterval此处使用运算符,它为您提供排放之间的时间以及值。设置如下:

  fromEvent(myInput.nativeElement, 'keydown').pipe(
    tap(e => e.preventDefault()),
    timeInterval(), // just add this operator, will convert to shape {value: T, interval: number}
    scan((acc: KeyboardEvent[], val) => {
      // Add condition here to manually reset the accumulator...
      // also check the interval
      if (acc.length === 3 || val.interval > 3000) {
        acc = [];
      }
      return [...acc, val.value];
    }, []),
    takeUntil(this.destroy$)
   ).subscribe((events: KeyboardEvent[]) => console.log(events));

这是一个有效的闪电战:https ://stackblitz.com/edit/rxjs-dxfb37?file=index.ts

不是我以前有过用例的操作员,但似乎在这里非常有效地解决了您的问题。


推荐阅读