angular - RxJs 限制订阅调用的数量
问题描述
我听 ResizeObserver (或者更确切地说,一个 polyfill )来触发一个fabricjs画布的重绘,这非常耗费资源。因此,我想限制由 resize 事件触发的重绘数量。
我尝试用 RxJs 实现这个功能:
- 立即触发重绘(第一次)
- 重绘在 n 毫秒内没有被触发
- 重绘确实会在 n 毫秒后触发
- 最后一次调整大小事件会触发重绘
RxJs 提供了一些内置的基于时间的操作符。但是,它们都有自己的缺陷:
- auditTime : 有一个初始延迟
- debounceTime:初始延迟,并且在您不断调整大小时永远不会触发
- throttleTime : 可能会忽略最后几个事件,这很关键
我尝试合并/加入这些运算符,但这导致 n 秒后重复调用和其他问题。有没有简单的 RxJs 方法来做到这一点?我想可以通过启动/清除超时功能来实现。
解决方案
您可以编写自己的函数并在局部变量中跟踪最后发出和接收的项目。要读取 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);
})
}
在此处通过一些测试查看它的实际效果。
推荐阅读
- mysql - 使用 SQL 文件在 Docker 容器中创建 MYSQL 表
- python - Django Rest Framework - 使用 Djoser “无法创建帐户”
- silverstripe - 子网站模块的 Silverstripe 错误:名为“CopyToSubsiteID”的字段出现两次
- vb.net - 将 Datagridview 列值获取到 Textbox1、Textbox2、Textbox3
- hibernate - 用于过滤两个子实体的 Spring Boot 规范
- python - 如何从 matplotlib 主干图中删除主干线?
- python-3.x - 在分组任务中分块子任务时出现类型错误
- count - 根据他们的资格计算员工
- java - 如何将我的 BottomNavigationView 与 Navigation Drawer 结合使用
- drools - getKieClasspathContainer() 方法返回空值