使用 RxJS 对元素拖动事件进行缓冲/节流处理

4
我希望实现一种情境,当连续的事件源(例如拖动元素)上发生某些事情时,加入一些缓冲/节流机制。我希望接收通知,例如:
  • 每400毫秒
  • 但仅在事件源中有新项目(实际发生了拖动)时
我的最佳想法是使用下面概述的节流运算符,它只会等待400毫秒的暂停,然后提供序列-它不会提供持续拖动的值:
Rx.Observable
      .fromEvent(element, "drag")
      .throttle(400);

我猜需要一个计时器源,但在这种情况下,如何将计时器源和拖动源与上述标准相结合?

1个回答

8
Rx使用Schedulers的概念(具体来说是Rx.Scheduler实例)。throttle方法需要一个可选的第二个参数,即要使用的调度程序。如果您不提供第二个参数,则使用Rx.Scheduler.timeout。此调度程序使用setTimeout在未来安排任务。
在您的示例中,这意味着每当发生拖动事件时,throttle将存储该事件并不会立即通知您。然后,它通过调度程序安排一个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) {
        // ...
    });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接