> For the complete documentation index, see [llms.txt](https://shenjunhong.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://shenjunhong.gitbook.io/blog/yuan-ma/yuan-ma-shou-xie-xi-lie/jie-liu-he-fang-dou.md).

# 两者对比

1. 防抖（Debounce）\
   原理：当事件被触发后，延迟一段时间（比如 300ms）再执行目标函数。如果在这段时间内事件再次被触发，就重新计时，只有当事件停止触发一段时间后，函数才会真正执行。

场景：适合需要“等一等”的情况，比如搜索框输入，用户输入完后再发起请求。

形象记忆：想象你在等人挤电梯。每次有人来（事件触发），你就重新等几秒，确保没人再来时才关门（执行函数）。如果一直有人来，你就一直推迟关门。

2. 节流（Throttle）\
   原理：在事件触发时，立即执行函数，但设置一个时间间隔（比如 300ms），在此间隔内即使事件再次触发，函数也不会再次执行，直到下个时间间隔到来。

场景：适合需要“控制频率”的情况，比如滚动监听、鼠标移动，确保函数不会过于频繁执行。

形象记忆：想象你在玩射击游戏，节流就像机关枪的射速限制——每秒只能射一次（固定间隔执行），不管你多快按扳机，子弹发射都有节奏。

防抖节流总结：

* 防抖函数一般用于表单搜索，点击事件等场景，目的就是为了防止短时间内多次触发事件。
* 节流函数一般为了降低函数执行的频率，比如滚动条滚动,鼠标跟踪。

## debounce

假设你正在乘电梯上楼，当电梯门关闭之前发现有人也要乘电梯，礼貌起见，你会按下开门开关，然后等他进电梯；\
如果在电梯门关闭之前，又有人来了，你会继续开门；\
这样一直进行下去，你可能需要等待几分钟，最终没人进电梯了，才会关闭电梯门，然后上楼。

1. debounce 函数会通过闭包维护一个 timer
2. 当同一 action 在 delay 的时间间隔内再次触发，则清理 timer，然后重新设置 timer

```js
const debounce = (fn, wait) => {
  var timerId = null;

  return function () {
    clearTimeout(timerId);
    timerId = setTimeout(() => {
      fn.apply(this, arguments);
    }, wait);
  };
};
```

所以 debounce 的作用是，**当调用动作触发一段时间后，才会执行该动作，若在这段时间间隔内又调用此动作则将重新计算时间间隔**。

## throttle

假设你正在乘电梯上楼，当电梯门关闭之前发现有人也要乘电梯，礼貌起见，你会按下开门开关，然后等他进电梯；\
但是，你是个没耐心的人，你最多只会等待电梯停留一分钟；\
在这一分钟内，你会开门让别人进来，但是过了一分钟之后，你就会关门，让电梯上楼。

```js
const throttle = (fn, wait) => {
  var wait = wait || 0;
  var lastTime = 0;

  return function () {
    var currentTime = +new Date();
    if (currentTime > lastTime + wait) {
      lastTime = currentTime;
      fn.apply(this, arguments);
    }
  };
};
```

```js
function debounce(fn, wait) {
  // 先说下是干啥的 防抖
  var timerId = null;
  // 电梯举例： 加入你坐电梯，你设置时间，在这个时间段内，只要有人按 你就会暂停。这个过程可能需要等待几分钟，最终没人进电梯了
  return function () {
    clearTimeout(timerId);
    timerId = setTimeout(() => {
      fn.apply(this, arguments);
    }, wait);
  };
}
```

```js
function throttle(fn, wait) {
  // 节流代表的意思是 你是个很没有耐心的人 throttle
  // 这个时间段内 执行多少次 你不管 ，只要超过了 这个时间 你就会走
  var lastTime = 0;
  return function () {
    currentTime = +new Date();
    if (currentTime > lastTime + wait) {
      lastTime = currentTime;
      fn.apply(this, arguments);
    }
  };
}
```

```ts
function debounce(fn, wait) {
  let timerId = null;
  return function () {
    clearTimeout(timerId);
    timerId = setTimeout(() => {
      fn.apply(this, arguments);
    }, wait);
  };
}
```

```typescript
function throttle(fn, wait) {
  var waite = wait || 0;
  var lastTime = 0;
  return function () {
    var currentTime = +new Date();
    if (currentTime > lastTime + waite) {
      lastTime = currentTime;
      fn.apply(this, arguments);
    }
  };
}
```

```js
//去抖动
const debounce = (fn, wait) => {
  var timerId = null;

  return function () {
    if (timerId) {
      clearTimeout(timerId);
    }
    timerId = setTimeout(() => {
      fn.apply(this, arguments);
    }, wait);
  };
};
```

```js
// 节流
const throttle = (fn, wait) => {
  var lastTime,
    wait = wait || 0;
  return function () {
    var currentTime = +new Date();
    if (currentTime - lastTime > wait) {
      lastTime = currentTime;
      fn.apply(this, arguments);
    }
  };
};
```
