4

当某些事情发生在连续的事件源(拖动元素)上时,我想实现一个场景 - 但有一些缓冲/节流。我想收到通知让我们说

  • 每 400 毫秒
  • 但前提是源中有新项目(实际发生了拖动)

我与下面概述的节流操作符最接近的想法只是等待 400 毫秒的暂停,然后提供序列 - 它不提供连续拖动的值:

Rx.Observable
      .fromEvent(element, "drag")
      .throttle(400);

我想需要一些定时器源,但在这种情况下,我如何将定时器源和拖动源与上述标准结合起来?

4

1 回答 1

8

Rx 使用SchedulersRx.Scheduler具体来说就是实例)的概念。该throttle方法接受一个可选的第二个参数,它是要使用的调度程序。如果您不提供第二个参数,则Rx.Scheduler.timeout使用 then。这个调度器setTimeout用来调度未来的事情。

在您的示例中,这意味着每当发生拖动事件时,throttle都会存储该事件并且不会告诉您。然后它从现在开始 400 毫秒安排一个动作(通过调度程序,最终意味着通过setTimeout)来通知您该事件。如果另一个drag事件在此超时到期之前到达,那么它将取消超时并开始一个新的。这是因为throttle只有在传入事件暂停至少 400 毫秒时才会通知您。这意味着如果你拖得非常快,那么在你最终放慢拖拽之前你不会得到任何事件。

从您的描述来看,您实际上可能更喜欢使用sample而不是throttle. 如果在该时间间隔内发生任何事件,将每nSample ms给您一个事件,例如

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) {
        // ...
    });
于 2013-04-28T21:18:39.630 回答