RxJS возьми сначала дроссель и жди

Я хочу наблюдать за mousewheel событие, использующее RxJS-DOM, чтобы при первом событии я включал его, а затем отбрасывал все значения до тех пор, пока задержка между последующими значениями не пройдет ранее заданную продолжительность.

Оператор, который я представляю, может выглядеть примерно так:

Rx.DOM.fromEvent(window, 'mousewheel', (e) => e.deltaY)
.timegate(500 /* ms */)

Представьте себе следующий поток данных:

0 - (200 ms) - 1 - (400ms) - 2 - (600ms) - 3

где отправляемое значение - это число, а время описывает, сколько времени потребуется для получения следующего значения. Поскольку 0 является первым значением, оно будет отправлено, а затем все значения до 3 будут отброшены, поскольку отдельные задержки между последующими значениями не превышают 500ms,

В отличие от газа, задержка между значениями рассчитывается независимо от того, испущено последнее полученное значение или нет. При использовании дросселя 0 будет отправлено, 200 мс пройдет, 1 будет оценено и завершится с ошибкой, 400 мс пройдет и 2 будет оценено и PASS, потому что время проходит между последним переданным значением (0) и текущим принятым (2)) составляет 600 мс, тогда как с моим оператором он будет оцениваться относительно 1, а время истечения будет 400 мс, поэтому проверка не пройдена.

И этот оператор тоже не дебас. Вместо того, чтобы ждать, пока истечет интервал для выдачи, он сначала отправляет первое значение, затем сравнивает его со всеми будущими значениями и так далее.

Такой оператор уже существует? И если нет, то как бы я сделал один?

2 ответа

Вы можете достичь этого относительно легко, используя timeInterval оператор, который точно вычисляет временной интервал между последовательными значениями. Вот пример кода, который вы можете адаптировать под свой облик.

http://jsfiddle.net/a7uusL6t/

var Xms = 500;
var click$ = Rx.Observable.fromEvent(document, 'click').timeInterval()
var firstClick$ = click$.first().map(function(x){return x.value});

var res$ = firstClick$
  .concat(click$
    .filter(function (x) {
      console.log('interval', x.interval);
      return x.interval > Xms;})
    .map(function(x){return x.value})
   );

res$.subscribe(function(x){console.log(x)})

Я решил свою проблему с чем-то похожим, но более изысканным, чем ответ @user3743222:

const events = Rx.Observable.fromEvent(window, 'mousewheel', (e) => e.deltaY);
const firstEventObservable = events.take(1);
const remainingEventsObservable = events.skip(1)
    .timeInterval()
    .filter(x => x.interval >= this.props.delayDuration)
    .map(x => x.value);
const pageChangeObservable = firstEventObservable.concat(remainingEventsObservable);
Другие вопросы по тегам