> For the complete documentation index, see [llms.txt](https://chanshiyu.gitbook.io/blog/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://chanshiyu.gitbook.io/blog/qian-duan/javascript/06-han-shu-jie-liu-yu-han-shu-fang-dou.md).

# 06 函数节流与函数防抖

函数节流（throttle）与函数防抖（debounce）核心思想都是通过限制函数调用来实现性能优化，但两者概念却有不同：

* 函数节流：函数按指定间隔调用，限制函数调用频率
* 函数防抖：一定时间段连续的函数调用，只让其执行一次

两者的使用场景也有不同：

* 函数节流：页面滚动事件监听（scroll）、DOM 元素拖拽（mousemove）、键盘事件（keydown）
* 函数防抖：文本输入验证发送请求、窗口缩放（resize）

## 函数节流

函数节流可以通过设置两个时间戳来实现，通过比较两个时间戳，让其在一定时间间隔内只执行一次，然后将时间戳重置为这次执行的时间，实现代码如下：

```javascript
function throttle(func, delay) {
  let lastCall = new Date()
  return function(...args) {
    const now = new Date()
    if (now - lastCall < delay) {
      return
    }
    lastCall = now
    return func.apply(this, args)
  }
}
```

loadsh.js 里的函数节流功能实现更为复杂，可以实现首调用和尾调用。这里不再细说，详情可以参考源码。

## 函数防抖

函数防抖可以通过定时器来实现，还可以设置第一次触发时是否立即执行：

```javascript
function debounce(func, wait, immediate = false) {
  let timeout
  return function(...args) {
    clearTimeout(timeout)
    timeout = setTimeout(() => {
      func.apply(this, args)
    }, wait)
    // 是否立即执行一次任务
    if (immediate) {
      immediate = false
      func.apply(this, args)
    }
  }
}
```
