2013-04-28 2 views
2

Я хотел бы реализовать сценарий, когда некоторые события происходят на непрерывном источнике событий (перетаскивание элемента), но с некоторой буферизацией/дросселированием. Я хотел бы получить уведомление, скажемСобытия перетаскивания элементов буфера/дросселя с RxJS

  • каждые 400 миллисекунд
  • но только если появились новые элементы в источнике (тянущие на самом деле произошло)

Моя ближайшая идея с оператором дроссельной заслонки изложенные ниже просто выжидает 400 мс пауза, а затем обеспечивает последовательность - это не дает значения на непрерывное сопротивление:

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

Я предполагаю некоторый источник времени, r, но в этом случае, как я могу объединить источник таймера и источник перетаскивания с вышеупомянутыми критериями?

ответ

6

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) { 
     // ... 
    });