我想实现一个场景,当某些事情发生在连续的事件源(拖动元素)上时 - 但有一些缓冲/节流。我想收到一条通知,比方说
- 每 400 毫秒
- 但前提是源中有新项目(确实发生了拖动)
我最接近下面概述的 throttle 运算符(operator)的想法只是等待 400 毫秒的暂停,然后提供序列 - 它不提供连续拖动的值:
Rx.Observable
.fromEvent(element, "drag")
.throttle(400);
我想可能需要一些计时器源,但在那种情况下,我如何将计时器源和拖动源与上述条件结合起来?
最佳答案
Rx 使用Scheduler
的概念(Rx.Scheduler
实例是具体的)。 throttle
方法有一个可选的第二个参数,它是要使用的调度程序。如果您不提供第二个参数,则使用 Rx.Scheduler.timeout
。此调度程序使用 setTimeout
来安排 future 的事情。
在您的示例中,这意味着无论何时发生拖动事件,throttle
都会存储该事件并且不会告诉您。然后它安排一个 Action 从现在开始 400 毫秒(通过调度程序,最终意味着通过 setTimeout
)通知您事件。如果另一个 drag
事件在此超时到期之前到达,那么它将取消超时并开始一个新的事件。这是因为 throttle
只会在传入事件暂停至少 400 毫秒后通知您。这意味着如果您拖动得非常快,那么在您最终减慢拖动速度之前您将不会收到任何事件。
根据您的描述,您实际上可能更喜欢使用 sample
而不是 throttle
。 Sample
将每 n 毫秒为您提供一个事件,如果在该时间间隔内发生任何事件,例如
Rx.Observable
.interval(500)
.sample(1500)
.take(5)
.subscribe(function (x) {
console.log('x: ' + x);
});
<script src='https://rawgit.com/Reactive-Extensions/RxJS/v.2.5.3/dist/rx.all.js'></script>
这将产生值:
"x: 1"
"x: 4"
"x: 7"
"x: 10"
"x: 13"
其中每个值是间歇值总和的平均值,即:
- (0 + 1 + 2)/3 = 1
- (3 + 4 + 5)/3 = 4
- ...
你会像这样使用它:
Rx.Observable
.fromEvent(element, 'drag')
.sample(400)
.subscribe(function (e) {
// ...
});
关于javascript - 使用 RxJS 缓冲/节流元素拖动事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16260948/