Skip to content

Instantly share code, notes, and snippets.

@kievsash
Created January 26, 2019 11:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kievsash/51a2ef1be6138e7d113f9bda15469d6c to your computer and use it in GitHub Desktop.
Save kievsash/51a2ef1be6138e7d113f9bda15469d6c to your computer and use it in GitHub Desktop.
Throttling notifications from multiple users with RxJS - with throttling by custom throttleSelectiveFilter operator
let Rx = window['rxjs'];
let {from, of, asyncScheduler} = Rx;
let {mergeMap, filter, delay} = Rx.operators;
console.clear();
let throttleSelectiveFilter = (throttleTime = 0, selector = (x) => x) => {
let setOfEntities = new Set();
return (source) => {
return source.pipe(
filter((notif) => {
if (throttleTime === 0) return true;
const id = selector(notif);
console.log('Checking id ', id, new Set(setOfEntities))
if (setOfEntities.has(id)) return false;
const clearId = setTimeout(() => {
clearTimeout(clearId);
setOfEntities.delete(id);
}, throttleTime);
setOfEntities.add(id);
return true;
})
)
}
}
let notifications = [
{ userId: 1, name: 'A1', delay: 100 }, // should be shown
{ userId: 1, name: 'A2', delay: 1500 }, // shouldn't be shown
{ userId: 1, name: 'A3', delay: 2500 }, // shouldn't be shown
{ userId: 1, name: 'A4', delay: 3500 }, // should be shown
{ userId: 2, name: 'B1', delay: 200 }, // should be shown
{ userId: 2, name: 'B2', delay: 300 }, // shouldn't be shown
{ userId: 2, name: 'B3', delay: 3500 }, // should be shown
]
let source$ = from(notifications).pipe(
mergeMap((notif) => {
return of(notif).pipe(delay(notif.delay));
}),
)
source$
.pipe(throttleSelectiveFilter(3000, (x) => x.userId))
.subscribe(showNotification);
let container = document.querySelector('.container');
function showNotification(notif) {
const newElem = document.createElement('div');
newElem.classList.add('item');
newElem.innerHTML = notif.name;
container.appendChild(newElem);
setTimeout(() => {newElem.remove()}, 800);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment