The previous solution with only firing of a task at the end of series of consecutive events had the obvious effect of updating the UI “late”: at the end of the event series. Now let’s do the opposite: fire off the task at the first event in the series, and simply supress the following events (so they don’t trigger firing off the task).
var EventSilencer = function() {
var mutedEvents = {};
var unmuteCallback = function(name) {
return function() {
delete mutedEvents[name];
};
};
var muteEvent = function(name, duration) {
var now = new Date().getTime();
var newUntil = now + duration;
var info = mutedEvents[name];
if (!info) {
info = {};
mutedEvents[name] = info;
info.timeoutId = setTimeout(unmuteCallback(name), newUntil - now);
info.until = newUntil;
return true;
} else if (newUntil > info.until) {
clearTimeout(info.timeoutId);
info.timeoutId = setTimeout(unmuteCallback(name), newUntil - now);
info.until = newUntil;
}
return false;
};
return function(name, fn, muteDuration) {
if (muteEvent(name, muteDuration)) {
fn();
}
};
}();