LS
前端小萌新!

防抖与节流函数

2019-11-06 js
Word count: 481 | Reading time: 2min

简介

在前端开发的过程中,我们经常会需要绑定一些持续触发的事件,如 resize、scroll、mousemove 等等,但有些时候我们并不希望在事件持续触发的过程中那么频繁地去执行函数。

一般采取防抖和节流的方法来解决此类问题

防抖(debounce)

所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。

防抖函数分为非立即执行版立即执行版

非立即执行版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function debounce(func, wait){
let timeout;
return function(){
let context = this;
let args = arguments;
if(timeout){
clearTimeout(timeout);
}
timeout = setTimeout(() => {
func.apply(context, args);
}, wait)

}
}

效果是第一次触发后延迟 n 秒再执行, 如果在 n 秒内又触发了事件,则会重新计算函数执行时间。

立即执行版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function debounce(func, wait){
let timeout;
return function(){
let context = this;
let args = arguments;
if(timeout){
clearTimeout(timeout);
}
let callnow = !timeout;
timeout = setTimeout(() => {
timeout = null;
}, wait);
if(callnow){
func.apply(context, args);
}
}
}

立即执行版的意思触发事件函数后将立即执行, 然后n秒内不触发事件才能继续执行函数的效果
具体看项目选用哪种防抖函数

节流(throttle)

所谓节流,就是连续触发函数在n秒中只执行一次,也就是控制函数触发的频率

节流有两种方式可以实现:定时器版时间戳版

定时器版

1
2
3
4
5
6
7
8
9
10
11
12
13
function throttle(func, wait){
let timeout;
return function(){
let context = this;
let args = arguments;
if(!timeout){
timeout = setTimeout(() => {
timeout = null;
func.apply(context, args);
}, wait)
}
}
}

时间戳版

1
2
3
4
5
6
7
8
9
10
11
12
function throttle(func, wait){
let start = 0;
return function(){
let context = this;
let args = arguments;
let curr = Date.now();
if(now - start > wait){
func.apply(context, args);
start = now;
}
}
}

参考文章: https://www.jianshu.com/p/c8b86b09daf0

Author: LS

Link: http://lshere.github.io/2019/11/06/%E9%98%B2%E6%8A%96%E4%B8%8E%E8%8A%82%E6%B5%81%E5%87%BD%E6%95%B0/

Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.

< 上一篇
mongoose多表查询 aggregate
下一篇 >
animation动画重复播放思路
目录
  1. 1. 简介
  2. 2. 防抖(debounce)
    1. 2.1. 非立即执行版
    2. 2.2. 立即执行版
  3. 3. 节流(throttle)
    1. 3.1. 定时器版
    2. 3.2. 时间戳版