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
оператор, который точно вычисляет временной интервал между последовательными значениями. Вот пример кода, который вы можете адаптировать под свой облик.
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);