2019-01-29 03:12:18 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* A function that emits a side effect and does not return anything.
|
|
|
|
|
*/
|
|
|
|
|
export type Procedure = (...args: any[]) => void
|
|
|
|
|
|
|
|
|
|
export type Options = {
|
|
|
|
|
isImmediate: boolean
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function debounce<F extends Procedure>(
|
|
|
|
|
func: F,
|
|
|
|
|
waitMilliseconds: number = 50,
|
|
|
|
|
options: Options = {
|
|
|
|
|
isImmediate: false
|
|
|
|
|
}
|
|
|
|
|
): F {
|
|
|
|
|
let timeoutId: NodeJS.Timeout | undefined
|
|
|
|
|
|
|
|
|
|
return function(this: any, ...args: any[]) {
|
|
|
|
|
const context = this
|
|
|
|
|
|
|
|
|
|
const doLater = function() {
|
|
|
|
|
timeoutId = undefined
|
|
|
|
|
if (!options.isImmediate) {
|
|
|
|
|
func.apply(context, args)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const shouldCallNow = options.isImmediate && timeoutId === undefined
|
|
|
|
|
|
2019-03-21 20:43:15 +01:00
|
|
|
if (!!timeoutId) {
|
2019-01-29 03:12:18 +01:00
|
|
|
clearTimeout(timeoutId)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
timeoutId = <any>setTimeout(doLater, waitMilliseconds)
|
|
|
|
|
|
|
|
|
|
if (shouldCallNow) {
|
|
|
|
|
func.apply(context, args)
|
|
|
|
|
}
|
|
|
|
|
} as any
|
|
|
|
|
}
|