関数が連続して呼び出されたとき、実行されるを最後の1回の呼び出しだけに限定してくれる、debounce
関数というものをTypeScriptで実装する方法です。
debounce関数は、例えば連打によるイベントの連続発火のせいで、関数が何度も実行されてしまうのを抑制したいときに便利です。
ここでは、実装方法を紹介しますが、車輪の再発明をしたくない人は、lodashの_.debounce()など、ライブラリもあるのでそちらを使ってみてください。
debounce関数の実装(TypeScript)
const debounce = <T extends (...args: any[]) => unknown>(
callback: T,
delay = 250,
): ((...args: Parameters<T>) => void) => {
let timeoutId: number // Node.jsの場合はNodeJS.Timeout型にする
return (...args) => {
clearTimeout(timeoutId)
timeoutId = setTimeout(() => callback(...args), delay)
}
}
動作デモ
まず、debounceされていない関数の実行例です。受け取った数値を出力する関数printNum
を10回連続して実行してみます:
const printNum = (n: number): void => {
console.log(n)
}
for (let i = 0; i < 10; i++) {
printNum(i)
}
出力結果は、0〜9がすべて出力されます:
0
1
2
3
4
5
6
7
8
9
次に、debounceされた関数を作り、それを同じように実行してみます:
const debouncedPrintNum = debounce(printNum)
for (let i = 0; i < 10; i++) {
debouncedPrintNum(i)
}
実行結果は、0〜8が間引かれ、9だけが出力されます:
9