module.exports = debounce; function debounce(fn, delay, atStart, guarantee) { var timeout; var args; var self; return function debounced() { self = this; args = Array.prototype.slice.call(arguments); if (timeout && (atStart || guarantee)) { return; } else if (!atStart) { clear(); timeout = setTimeout(run, delay); return timeout; } timeout = setTimeout(clear, delay); fn.apply(self, args); function run() { clear(); fn.apply(self, args); } function clear() { clearTimeout(timeout); timeout = null; } }; }