前言
开始正式文章之前,先来说一种我们在前端开发过程中经常会遇到的场景。在页面中通常都会有输入框用作搜索数据,而这些数据往往由前端发送请求到后端获取,如果用户一直在输入框中输入,那么将会一直不停地发送请求,显然这不是我们想看到的结果,而防抖与节流将能够对此应用场景做出优化。
防抖
防抖:当持续触发某事件时,并不立马执行事件处理函数,而是在一定时间内不再触发事件时才会执行一次,如果设定的时间到来之前,又一次触发了事件,那就重新计时。
现在用鼠标的onmousemove事件模拟这个过程:
- 未使用防抖
鼠标一放上去就执行多次,如果这是请求,就会短时间内大量请求,影响整体性能。 - 使用防抖函数
当onmousemove结束后1s再执行print函数,这里用到闭包,不了解的,可以看我的文章《谈谈什么是闭包?》
let num = 0;
//防抖函数
function debounce(fn, delay){
let timer = null;
return function () {
if (timer){
clearTimeout(timer);
}
timer = setTimeout(fn, delay);
}
}
function print(){
console.log("已执行" + ++num + "次");
}
document.getElementById("box").onmousemove = debounce(print, 1000)
节流
节流:当持续触发事件时,保证一定时间段内只调用一次事件处理函数。事件虽然持续触发,但是我们可以设定一个固定时间间隔去执行它,每隔多长时间执行一次,而非一直去执行。前言中提到的应用场景就非常适合用节流的思路来解决,就以此为例来演示节流。
- 未使用节流
未使用节流时,每次进行输入都会执行事件函数。 - 使用节流
每一秒钟执行一次输出
let num = 0;
//节流函数
function throttle(fn, delay){
let timer = null;
let nextFlag = true; //用标志位来判断是否结束了一次执行
return function () {
if (nextFlag){
nextFlag = false;
timer = setTimeout(function () {
fn();
nextFlag = true;
}, delay);
}
}
}
function print(){
console.log(`已执行${++num}"次, ${document.getElementById("search").value}`);
}
document.getElementById("search").onkeydown = throttle(print, 1000)