/** * Returns a function, that, as long as it continues to be invoked, will not * be triggered. The function will be called after it stops being called for * N milliseconds. If `immediate` is passed, trigger the function on the * leading edge, instead of the trailing. The function also has a property 'clear' * that is a function which will clear the timer to prevent previously scheduled executions. * * @source underscore.js * @see http://unscriptable.com/2009/03/20/debouncing-javascript-methods/ * @param {Function} function to wrap * @param {Number} timeout in ms (`100`) * @param {Boolean} whether to execute at the beginning (`false`) * @api public */ export function Debounce(func: Function, wait?: number, immediate?: boolean) { let timeout, args, context, timestamp, result if (null == wait) wait = 100 function later() { let last = Date.now() - timestamp if (last < wait && last > 0) { timeout = setTimeout(later, wait - last) } else { timeout = null if (!immediate) { result = func.apply(context, args) context = args = null } } } let debounced = function () { context = this args = arguments timestamp = Date.now() let callNow = immediate && !timeout if (!timeout) timeout = setTimeout(later, wait) if (callNow) { result = func.apply(context, args) context = args = null } return result } return debounced }