当源激发速率很快时,Rxjs缓冲

时间:2018-04-10 11:58:30

标签: rxjs rxjs5

让我们说,例如,我有一个可观察到的每秒x0次发射(可能是50,60,......),有时它只是每秒1或2次发射。

现在我怎样才能缓冲那些快速的动作并仍然处理慢速动作。

我累了:

BufferTime需要一个时间跨度,因此即使一个emition将被缓冲,(加上BufferTime使量角器测试超时)。

在收到所有x个emions之前,BufferCount(x)不会发出。

2 个答案:

答案 0 :(得分:1)

听起来你想要与debounce + buffer类似的东西。最简单的实现是使用流的去抖动来触发发出相同流的缓冲区。您可能希望共享流以防止重复订阅。这是一个运行的例子:

const source = new Rx.Observable.create((o) => {
  let count = 0;
  const emit = () => {
    const timeout = Math.random() * 1000;
    setTimeout(() => {
      o.next(count++);
      if (count < 20) {
      	emit();
      } else {
        o.complete();
      }
    }, timeout);
  };
  emit();
}).share();

const triggerBuffer = source.debounceTime(500);
source.buffer(triggerBuffer).subscribe((x) => { console.log(x); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.9/Rx.min.js"></script>

请注意,去抖动没有上限,因为如果它在去抖动时间内继续接收值,它就不会发出。实际上,这不应该对您的场景产生影响,但在其他情况下它理论上可以。

答案 1 :(得分:0)

正如bygrace所言,您正在寻找的是debounce + buffer

在现代RXJS 6中,并使用ES6 Typescript来添加类型推断,我创建了一个自定义的OperatorFunction来做到这一点非常简单,称为 bufferDebounce

type BufferDebounce = <T>(debounce: number) => OperatorFunction<T, T[]>;

const bufferDebounce: BufferDebounce = debounce => source =>
  new Observable(observer => 
    source.pipe(buffer(source.pipe(debounceTime(debounce)))).subscribe({
      next(x) {
        observer.next(x);
      },
      error(err) {
        observer.error(err);
      },
      complete() {
        observer.complete();
      },
  })
// [as many sources until no emit during 500ms]
source.pipe(bufferDebounce(500)).subscribe(console.log);

您可以在这里https://stackblitz.com/edit/rxjs6-buffer-debounce

看到一个有效的示例

希望这对您和所有新来者都有帮助。