Reputation: 148524
I let a user scroll a page and in every scroll event - I'm checking if there's a new items in the viewport
( if there are , I do some operation on those new items - irrelevant for now).
So I have something like this :
const observable = Rx.Observable.fromEvent(window, 'scroll');
const subscriber = observable.throttleTime(300 /* ms */).subscribe(
(x) => {
console.log('Next: event!');
},
(err) => {
console.log('Error: %s', err);
},
() => {
console.log('Completed');
});
This code is working as expected and I do see a message after each 300 ms.
But there's a problem. A user might scroll while not completing the 300 ms ( event won't be raised) and a new item got visible while scrolling.
This is where I need the debounce
method. (which means "after X ms of last event time - raise an event")
Which is exactly what I need.
const subscriber = observable.throttleTime(300 /* ms */).debounceTime(350)....
But I only see the debounced events.
Question
How can I use throttle and at the end of a throttle - attach a debounce ?
Upvotes: 11
Views: 5355
Reputation: 636
here is updated solution due to rxjs changes
import { fromEvent } from 'rxjs';
import { debounceTime, map, throttleTime } from 'rxjs/operators';
const observable = fromEvent(window, 'scroll');
const subscriber = observable
.pipe(
throttleTime(300 /* ms */),
map((data) => {
console.log('throttle');
console.log(window.pageYOffset);
return data;
}),
debounceTime(350)
)
.subscribe(
(x) => {
console.log(window.pageYOffset);
},
(err) => {
console.log('Error: %s', err);
},
() => {
console.log('Completed');
}
);
Upvotes: 2
Reputation: 45121
You could merge two streams: throttled and debounced into one using merge
. Demo.
const observable = Rx.Observable.fromEvent(window, 'scroll');
const subscriber = observable
.throttleTime(300 /* ms */)
.map(() => 'throttle')
.merge(observable
.debounceTime(350)
.map(() => 'debounce')
)
.subscribe(
(x) => {
console.log('Next: event!', x);
},
(err) => {
console.log('Error: %s', err);
},
() => {
console.log('Completed');
});
Upvotes: 8