首页 > 解决方案 > RxJs 限制订阅调用的数量

问题描述

我听 ResizeObserver (或者更确切地说,一个 polyfill 来触发一个fabricjs画布的重绘,这非常耗费资源。因此,我想限制由 resize 事件触发的重绘数量。

我尝试用 RxJs 实现这个功能:

  1. 立即触发重绘(第一次)
  2. 重绘在 n 毫秒内没有被触发
  3. 重绘确实会在 n 毫秒后触发
  4. 最后一次调整大小事件会触发重绘

RxJs 提供了一些内置的基于时间的操作符。但是,它们都有自己的缺陷:

我尝试合并/加入这些运算符,但这导致 n 秒后重复调用和其他问题。有没有简单的 RxJs 方法来做到这一点?我想可以通过启动/清除超时功能来实现。

标签: angularrxjsobservable

解决方案


您可以编写自己的函数并在局部变量中跟踪最后发出和接收的项目。要读取 Rx 中的时间,您应该使用scheduler.now(),这使您的代码可测试。您可以通过switchMap使用来模拟油门行为switchMap(()=>of(e).pipe(delay(duration)))。使用它,我们可以特殊情况下最后一项是很久以前的情况,我们想立即发出下一项。

这导致了以下解决方案:

function limitTime(duration, scheduler = async) {
  return (src) => new Observable(ob => {
      var last = scheduler.now() - duration;
      return src.pipe(
          switchMap(e => {
            var last2 = last;
            last = scheduler.now();
            if(last - last2 > duration) {
              return of(e);
            }
            return of(e).pipe(delay(duration + last2 - last, scheduler),
                             tap(() => last = scheduler.now()));
          })
        ).subscribe(ob);
    })
}

在此处通过一些测试查看它的实际效果。


推荐阅读