# 两者对比

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);
    }
  };
};
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://shenjunhong.gitbook.io/blog/yuan-ma/yuan-ma-shou-xie-xi-lie/jie-liu-he-fang-dou.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
