今天来介绍一下防抖(debounce)
和节流(throttle)
,相信大家对这俩词肯定不陌生,今天主要是希望可以用最简单的方式帮大家弄懂防抖和节流, 那我们直接进入主题吧~~
概念介绍
首先来看一下,防抖(debounce)
和节流(throttle)
的概念.
函数防抖debounce
- 概念: 事件停止触发指定时间后再执行函数,如果在这时间又被触发,则不触发重新计时.
- 举例: 开始拖动地图,设定1000ms后触发请求数据,如果在1000ms内我停止拖动了,则直接请求数据,如果1000ms内我再次触发拖动事件,则重新计时,不触发请求.
函数节流throttle:
- 概念: 在指定的时间间隔内,一定会只执行一次函数
- 举例: 开始拖动地图,设定500ms后触发请求数据,在500ms内无论我停止还是继续拖动,到500ms时就会触发一次.
场景介绍
函数防抖debounce
- 搜索: 最常见的就input,不断输入,会导致不断的请求,可以用防抖来节约请求资源.
- resize: 当我们不断的调整浏览器窗口大小的时候,会不断的触发resize事件,可以用防抖来控制其触发次数
- 地图拖动: 拖动过程中,需要加载当前可视窗覆盖物数据,如果不停拖动,会触发多次请求,导致地图卡顿,可以用防抖来控制请求次数
函数节流throttle:
- 鼠标点击: 不断点击会导致不断触发,可以用节流控制其指定时间内只触发一次
- 滚动事件: 页面数据过长,可以通过节流来控制滚动指定时间内加载一次数据
案例
input
案例网上大把有,都写的挺好的,大家可以自行百度/Google
, 我就以BMap
拖动为例,分别用debounce
和throttle
的方式来实现
先来看一下,没有防抖节流的情况下
,拖动地图时,请求的情况(请求触发的动作在这里用console.log
代替)
const map = new BMapGL.Map('container');
map.centerAndZoom(new BMapGL.Point(116.404, 39.928), 15);
map.enableScrollWheelZoom(true);
// dragend: 停止拖拽地图时触发
map.addEventListener('dragend', (e: any) => {
console.log('拖动停止触发', e.latlng);
});
来看下效果
从图中可以看到,拖动停止的时候就会触发请求,但是有时候,我们并没有拖动到目的地,但是手机屏幕可拖动的区域是有限的,必须要停止在继续拖动,这样其实是很浪费资源的,而且如果时间过长对性能也是有影响的,可见这并不是很好的方式.
防抖案例
首先我们用防抖
的方式来解决这个问题,上代码:
// debounce.ts
const debounce = (func: Function, delay: number) => {
let timer: any = null;
// 接受函数的所有参数
return (...args: any[]) => {
clearTimeout(timer);
timer = setTimeout(() => {
func(...args);
timer = null;
}, delay);
};
};
// 调用
const map = new BMapGL.Map('container');
map.centerAndZoom(new BMapGL.Point(116.404, 39.928), 15);
map.enableScrollWheelZoom(true);
const debounceGet = debounce((val: any) => {
console.log('debounce-拖动地图', val.latlng);
}, 1000);
map.addEventListener('dragend', (e: any) => {
debounceGet(e);
});
来看下效果
从图中可以看到,并不是在我们每次拖动停止的时候就请求数据,当拖动停止后1000ms就会去请求数据,如果1000ms内还保持拖动的状态,是不会请求数据的.
节流案例
首先我们用节流
的方式来解决这个问题,上代码:
// throttle.ts
const throttle = (func: Function, delay: number) => {
let last = 0;
let timer: any = null;
return (...args: any[]) => {
const curr = new Date().getTime();
clearTimeout(timer);
if (last && curr - last >= delay) {
func(...args);
last = curr;
} else {
timer = setTimeout(() => {
func(...args);
last = curr;
}, delay);
}
};
};
// 调用
const map = new BMapGL.Map('container');
map.centerAndZoom(new BMapGL.Point(116.404, 39.928), 15);
map.enableScrollWheelZoom(true);
const throttleGet = throttle((val: any) => {
console.log('throttle-拖动地图', val.latlng);
}, 1000);
map.addEventListener('dragend', (e: any) => {
throttleGet(e);
});
来看下效果
从图中可以看到,并不是在我们每次拖动停止的时候就请求数据,但是拖动过程中,每1000ms就会去请求一次数据.
以上就是防抖和节流的全部内容了,大家在实际开发过程中可以根据需求决定使用哪种,希望本文对大家有所帮助~
关注UU
关注公众号【前端UU】
, 定期获取好文推荐哟~
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!