Reputation: 6458
Is there an operator in RxJS that debounces without delaying the "first event in a burst", but delaying (and always emitting) the "last event in a burst"?
Something like this:
---a----b-c-d-----e-f---
after awesome-debounce(2 dashes)
becomes:
---a----b------d--e----f
while a normal debounce would be:
-----a---------d-------f
It's kind of a mix between throttle and debounce...
Upvotes: 8
Views: 3208
Reputation: 2683
That's indeed useful debounce type for many situations. Use merge
, throttleTime
and debounceTime
in a next way:
Rx.Observable.merge(source.throttleTime(1000), source.debounceTime(2000))
Full example is here http://jsbin.com/godocuqiwo/edit?js,console
Note: it will emit not only first and last value in debounce interval but also values produced by throttle (which is usually expected and needed, as for scroll debouncing for example).
Upvotes: -1
Reputation: 96969
Hmmm, this is the easiest solution I can think of. The interesting part for you is the awesomeDebounce()
function that creates the sub-chain.
It basically just combines throttle()
and debounceTime()
operators:
const Rx = require('rxjs');
const chai = require('chai');
let scheduler = new Rx.TestScheduler((actual, expected) => {
chai.assert.deepEqual(actual, expected);
console.log(actual);
});
function awesomeDebounce(source, timeWindow = 1000, scheduler = Rx.Scheduler.async) {
let shared = source.share();
let notification = shared
.switchMap(val => Rx.Observable.of(val).delay(timeWindow, scheduler))
.publish();
notification.connect();
return shared
.throttle(() => notification)
.merge(shared.debounceTime(timeWindow, scheduler))
.distinctUntilChanged();
}
let sourceMarbles = '---a----b-c-d-----e-f---';
let expectedMarbles = '---a----b------d--e----f';
// Create the test Observable
let observable = scheduler
.createHotObservable(sourceMarbles)
.let(source => awesomeDebounce(source, 30, scheduler));
scheduler.expectObservable(observable).toBe(expectedMarbles);
scheduler.flush();
The inner notification
Observable is used only for the throttle()
operator so I can reset its timer manually when I need. I also had to turn this Observable into "hot" to be independent on the internal subscriptions from throttle()
.
Upvotes: 8