---
# System prepended metadata

title: throttle 節流 & debounce 防抖處理
tags: [節流, 防抖, 前端基礎知識]

---

## 控制事件觸發頻率

### 事件觸發平凡可能造成的原因與問題：
* 有一些瀏覽器事件window.onresize, window.mousemove等，觸發頻率很高，會造成界面卡頓
* 如果像後端發送request，頻繁觸發，對server造成不必要壓力

## throttle()節流

* 語法：throttle(callback, wait)
* 功能：創建一個節流函數，在wait毫秒內最多執行callback一次
* 理解：
    * 在函式需要頻繁觸發時，函數執行一次後，只有大於設定的執行週間後才會執行第二次
    * 適合多次事件按時間做平均分配觸發
* 場景：
    * 窗口調整resize
    * 頁面滾動scroll
    * DOM元素的拖曳功能實現mousemove
    * 搶購瘋狂點擊click

### 程式碼 - 節流

```
function throttle(callback, waitTimes){
    //定義開始時間
    let start = 0;
    
    //事件觸發當下回傳一個function
    return function(e){
    //判斷當前觸發時間與start間隔是否到達條件
    let now = Date.now();
    
    if(now - start >= waitTimes){
        //滿足，執行callback
        callback.call(this, e)
        //修改開始時間
        start = now
    }
    }
}
```

```
 window.addEventListener('scroll', throttle(function(e){
    //這裡為callback要執行的程式碼
 }, waitTimes))
```



## debounce()防抖
* 語法：debounce(callback, wait)
* 功能：創建一個防抖函數，該函數會從上一次被調用後，延遲wait毫秒後調用callback
* 在第一次觸發事件後，如果在等待的秒數中，又去執行一次那計時器就會重新計算，如果又再一次觸發事件，那又會再重新計時。直到某次事件觸發後在等待的秒數內沒有再觸發事件，才會執行callback

### 程式碼 - 防抖

情境：相關關鍵字搜索

```
function debounce(callback, time){
    //定時器變量
    let timeId = null;
    //判斷
    if(timeId !== null){
        //清空定時器
        clearTimeOut(timeId);
    }
    //啟動定時器
    timeId = setTimeOut(() => {
        callback.call(this, e)
        //重置定時器
        timeId = null
    })
}
```

```
let input = document.querySelector('input')
input.onkeydown = debounce(function(e){
    console.log(e.keyCode)
}, 1000)

```