当事件触发时,相应的函数并不会立即触发,而是会等待一定的时间

当事件密集触发时,函数的触发会被频繁的推迟;

只有等待了一段时间也没有事件触发,才会真正的执行响应函数;

防抖的应用场景很多:

  • 输入框中频繁的输入内容,搜索或者提交信息;
  • 频繁的点击按钮,触发某个事件;
  • 监听浏览器滚动事件,完成某些特定操作;
  • 用户缩放浏览器的 resize 事件;

案例

在某个搜索框中输入自己想要搜索的内容:

比如想要搜索一个 MacBook:

  • 当输入 m 时,为了更好的用户体验,通常会出现对应的联想内容,这些联想内容通常是保存在服务器的,所以需要一次网络请求;
  • 当继续输入 ma 时,再次发送网络请求;
  • 那么 macbook 一共需要发送 7 次网络请求;
  • 这大大损耗整个系统的性能,无论是前端的事件处理,还是对于服务器的压力;

但是我们需要这么多次的网络请求吗?

  • 不需要,正确的做法应该是在合适的情况下再发送网络请求;
  • 比如如果用户快速的输入一个 macbook,那么只是发送一次网络请求;
  • 比如如果用户是输入一个 m 想了一会儿,这个时候 m 确实应该发送一次网络请求;
  • 也就是我们应该监听用户在某个时间,比如 500ms 内,没有再次触发时间时,再发送网络请求;

这就是防抖的操作:只有在某个时间内,没有再次触发某个函数时,才真正的调用这个函数;

实现

1
2
3
4
5
6
7
8
export default function myDebounce(fn, delay) {
let timer: null | number = null;
return function _debounce(...args) {
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}

第一次是否立即执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type fn = () => void;
export default function myDebounce(fn: fn, delay: number, immediate = true) {
let timer: null | number = null;
let isInvoke: boolean = false;
return function _debounce(...args) {
if (timer) clearTimeout(timer);
// 第一次是否立即执行
if (immediate && !isInvoke) {
fn.apply(this, args);
isInvoke = true;
return;
}
timer = setTimeout(() => {
fn.apply(this, args);
timer = null;
}, delay);
};
}

当事件触发时,相应的函数并不会立即触发,而是会等待一定的时间

当事件密集触发时,函数的触发会被频繁的推迟;

只有等待了一段时间也没有事件触发,才会真正的执行响应函数;

防抖的应用场景很多:

  • 输入框中频繁的输入内容,搜索或者提交信息;
  • 频繁的点击按钮,触发某个事件;
  • 监听浏览器滚动事件,完成某些特定操作;
  • 用户缩放浏览器的 resize 事件;

案例

在某个搜索框中输入自己想要搜索的内容:

比如想要搜索一个 MacBook:

  • 当输入 m 时,为了更好的用户体验,通常会出现对应的联想内容,这些联想内容通常是保存在服务器的,所以需要一次网络请求;
  • 当继续输入 ma 时,再次发送网络请求;
  • 那么 macbook 一共需要发送 7 次网络请求;
  • 这大大损耗整个系统的性能,无论是前端的事件处理,还是对于服务器的压力;

但是我们需要这么多次的网络请求吗?

  • 不需要,正确的做法应该是在合适的情况下再发送网络请求;
  • 比如如果用户快速的输入一个 macbook,那么只是发送一次网络请求;
  • 比如如果用户是输入一个 m 想了一会儿,这个时候 m 确实应该发送一次网络请求;
  • 也就是我们应该监听用户在某个时间,比如 500ms 内,没有再次触发时间时,再发送网络请求;

这就是防抖的操作:只有在某个时间内,没有再次触发某个函数时,才真正的调用这个函数;

实现

1
2
3
4
5
6
7
8
export default function myDebounce(fn, delay) {
let timer: null | number = null;
return function _debounce(...args) {
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}

第一次是否立即执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type fn = () => void;
export default function myDebounce(fn: fn, delay: number, immediate = true) {
let timer: null | number = null;
let isInvoke: boolean = false;
return function _debounce(...args) {
if (timer) clearTimeout(timer);
// 第一次是否立即执行
if (immediate && !isInvoke) {
fn.apply(this, args);
isInvoke = true;
return;
}
timer = setTimeout(() => {
fn.apply(this, args);
timer = null;
}, delay);
};
}