什么是函数节流?
概念:限定一个函数在一定时间内只能执行一次,执行的是第一次
为什么需要函数节流(防抖)?
前端开发过程中,有一些事件/函数会被频繁地触发,例如onresize、scroll、mousehover等鼠标事件,这些事件的触发频率很高,不做限制的话,每秒内执行几十次甚至更多,会造成计算机资源的浪费.
如果函数内部执行了DOM操作,会降低程序运行速度,容易造成浏览器卡死、崩溃.
如果函数内部执行了ajax,会造成请求数据混乱、网络阻塞、占用服务带宽、增加服务器压力
实现思路
给一个标志,根据这个标志去判断是否执行,执行完取反这个标志
根据两次时间戳的差判断,执行完后更新原始时间戳变量
实现方案
// 定时器方案
function throttle (fn, wait){
var time = null;
return function(){
if(!timer) {
timer = setTimeout(function(){
fn.applay(this,arguments);
timer = null;
},wait)
}
}
}
function test(){
console.log(Math.random());
}
window.addEventListener("mousehover", throttle(test, 1000));
//时间戳方案
function throttle (fn, wait){
var pre = Date.now();
return function(){
var now = Date.now();
if(now - pre >= wait) {
timer = setTimeout(function(){
fn.applay(this,arguments);
pre = Date.now();
},wait)
}
}
}
function test(){
console.log(Math.random());
}
window.addEventListener("mousehover", throttle(test, 1000));
使用场景
1.滚动加载、监听滚动条位置
2.百度搜索框、搜索联想/推荐功能
3.高频点击提交、重复表单提交
扩展补充对比:函数防抖
概念:频繁触发后,会清除掉前一次的执行,限定时间后,执行最后一次触发的防抖函数
思路:通过闭包保存一个标记来保存setTimeout返回的值,每当用户输入的时候把前一个setTimeoutclear 掉,然后又创建一个新的setTimeout,这样就能保证interval间隔内如果还有触发操作的话,就不会执行fn函数了。
实现方案:
function debounce(fn, interval = 300) {
let timeout = null;
return function () {
clearTimeout(timeout);
timeout = setTimeout(() => {
fn.apply(this, arguments);
}, interval);
};
}