如何将rrjjs中的Scheduler.animationFrame和fromEvent(window,'scroll')流结合起来?
我有两个观察对象Observable.of(0, animationFrame)
& Observable.fromEvent(window, 'scroll')
。我想合并它们,这样我的renderScrollBar(event)
只在animationFrame的tick上被调用。如何将rrjjs中的Scheduler.animationFrame和fromEvent(window,'scroll')流结合起来?
Observable.fromEvent(window, 'scroll')
.map((event: any) => event.currentTarget)
.subscribe((event) => {
this._renderScrollBar(event);
});
let x = 0;
Observable.of(0, animationFrame)
.repeat()
.takeUntil(Observable.timer(1000))
.subscribe(() => console.log(x++));
}
如果要将滚动事件调整为requestAnimationFrame,则可以使用throttleTime(0, animationFrame)
运算符而不是Observable.of(0, animationFrame)
。
例
Observable.fromEvent(window, 'scroll')
.throttleTime(0, animationFrame)
zip
是一个快速和肮脏的解决方案,具有潜在的严重缺陷:真正的滚动值背后的滚动处理滞后滚动时发出的事件比帧速率更快。它看起来是这样的:
Observable.fromEvent(window, 'scroll')
.map(event => event.currentTarget)
.zip(Observable.of(0, animationFrame)
.repeat(),
(currentTarget, _) => this._renderScrollBar(currentTarget)
);
如果需要event
包含了最新的滚动信息,你可能需要求助于更复杂的解决方案与the window
operator,如:
Observable.fromEvent(window, 'scroll')
.map(event => event.currentTarget)
.window(Observable.of(0, animationFrame).repeat())
.mergeMap(w => w.takeLast(1))
.subscribe(currentTarget => this._renderScrollBar(currentTarget));
- 至上,
window
从源创建一个Observable块,每次参数Observable发出一个项目时都会分块。在这种情况下,一系列滚动事件由每个动画片段分块。 - 如果块不为空,我们只取每块的最新版本,并将
mergeMap
修改为平面输出流。空的块将不会贡献任何项目到这最后的流。
它似乎正在工作,但我得到一个错误 EmptyError {名称:“EmptyError”,堆栈:“EmptyError:序列中没有元素,消息:”序列中没有元素“ } 消息 : “在序列中没有元素” 名 : “EmptyError” 栈 : “EmptyError:按顺序 –
没有元素@MatthewHarwood我的坏,'takeLast(1)'是你想要的,如不会抛出空的流。 – concat
我不认为有任何简单的方法来运行在RxJS每animationFrame动作。 – martin
是[zip](http://reactivex.io/documentation/operators/zip.html)您正在查找的行为? – concat
@concat我认为你能够在答案中做出样本?我会试试看,并将其标记为正确 –