如何为RxJs订阅中的缓冲和去抖动添加限制

时间:2019-03-22 14:09:46

标签: angular rxjs

我想使用RxJs实现以下目标:

  1. 在上一条消息的大约200ms之内分组消息
  2. 在250毫秒内未收到新消息时发出一组消息
  3. 当一组消息达到10条时发出消息。

由于有关于SO的其他几个问题,例如this one,使用bufferdebounceTime的组合很容易实现1和2,就像这样:

const subject$ = new Subject<number>();

// Create the debounce
const notifier$ = subject$.pipe(
  debounceTime(250)
);

// Subscribe to the subject using buffer and debounce
subject$
  .pipe(
    buffer(notifier$)
  )
  .subscribe(value => console.log(value));

// Add a number to the subject every 200ms untill it reaches 10
interval(200)
  .pipe(
    takeWhile(value => value <= 10),
  )
  .subscribe(value => subject$.next(value));

只要在最后一条消息的200ms之内发出消息,这些消息就会被缓冲。如果花费超过200毫秒,则会启动一个新的缓冲区。但是,如果消息持续不到200毫秒,则消息可能会永远被缓冲。这就是为什么我要对缓冲区大小添加硬限制。

我在StackBlitz创建了一个示例来演示缓冲区的去抖动。但是我不知道如何限制缓冲区,以便它也可以在达到10个项目时发出。

2 个答案:

答案 0 :(得分:1)

我们可以创建另一个通知程序来限制项数(例如,使用elementAt),使用首先发出的通知程序(使用race)并递归应用(使用expand ):

const notifierDebouncing$ = subject$.pipe(
  debounceTime(PERIOD),
  take(1)
);

const notifierLimiting$ = subject$.pipe(
  elementAt(AMOUNT - 1)
);

const notifier$ = interval(0).pipe(
  take(1),
  expand(_ => race(notifierLimiting$, notifierDebouncing$))
);

subject$
  .pipe(buffer(notifier$))
  .subscribe(value => console.log(value));

你怎么看?

以下是一个示例,该示例基于您的演示应用程序:https://stackblitz.com/edit/rxjs-buffer-debounce-cf4qjy (打开控制台,然后将光标移动2000ms,然后停止500ms)

答案 1 :(得分:0)

您不能只过滤它的第十个项目吗?也许我误解了你的问题。

    interval(this.interval)
      .pipe(
        filter(value => value % 10 === 0),
        takeWhile(value => value <= this.amount),
      )
      .subscribe(value => this.subject$.next(value));
  }