I'm not aware of any way to do this with without creating your own operator because you need to maintain some sort of state (the last seen value).
One way looks something like this:
// I named this debounceDistinctUntilChanged but that might not be
// the best name. Name it whatever you think makes sense!
function debounceDistinctUntilChanged(delay) {
const source$ = this;
return new Observable(observer => {
// Using an object as the default value
// so that the first time we check it
// if its the same its guaranteed to be false
// because every object has a different identity.
// Can't use null or undefined because source may
// emit these!
let lastSeen = {};
return source$
.debounce(value => {
// If the last value has the same identity we'll
// actually debounce
if (value === lastSeen) {
return Observable.timer(delay);
} else {
lastSeen = value;
// This will complete() right away so we don't actually debounce/buffer
// it at all
return Observable.empty();
}
})
.subscribe(observer);
});
}
Now that you see an implementation you may (or may not) find it differs from your expectations. Your description actually left out certain details, like if it should only be the last value you keep during the debounce time frame or if it's a set--basically distinctUntilChanged
vs. distinct
. I assumed the later.
Either way hopefully this gives you a starting point and reveals how easy it is to create custom operators. The built in operators definitely do not provide solutions for everything as-is, so any sufficiently advanced app will need to make their own (or do the imperative stuff inline without abstracting it, which is fine too).
You can then use this operator by putting it on the Observable prototype:
Observable.prototype.debounceDistinctUntilChanged = debounceDistinctUntilChanged;
// later
source$
.debounceDistinctUntilChanged(400)
.subscribe(d => console.log(d));
Or by using let
:
// later
source$
.let(source$ => debounceDistinctUntilChanged.call($source, 400))
.subscribe(d => console.log(d));
If you can, I recommend truly understanding what my code does, so that in the future you are able to easily make your own solutions.
distinctUntilChanged(compare: function)
allows you to define an arbitrary comparator where you could check the time between emissions (maybe even use the timestamp operator as well). – Lippe