防抖和节流
函数节流和函数防抖,两者都是优化高频率执行js代码的一种方法
防抖(debounce):只要不是最后一次触发就不会发送异步请求(定时器实现)。
节流(throttle):只要第一次请求发送后,响应没回来,就不能发送第二次请求(开关变量实现)。
防抖
现象
看下以下代码(模拟客户端向服务器发送请求):
window.onscroll = function () {
console.log("发送agax请求,加载更多...");
};
可以看到,我仅仅向下滑动了3次,向上滑动了三次就发出了将近70次请求。
解决
提前准备一个定时器,每次触发事件时都去看看定时器是不是空,不是的话取消之前的定时器,是的话就开始新一轮的等待。
var timer;
window.onscroll = function () {
//如果当前timer不是空,说明前边有一个等待的请求还未发送,还未发送。就停止前面的等待,
if (timer !== undefined) {
clearTimeout(timer);
}
// 从新开始下一轮的等待
timer = setTimeout(function () {
// 只有当200ms内未发生滚动是才发送正式的ajax请求;
console.log("发送agax请求,加载更多...");
}, 200);
};
节流
现象
看下以下代码(模拟客户端向服务器发送请求):
<body style="height: 2000px">
<button
id="btn"
style="position: fixed; right: 0; bottom: 200px"
onclick="clickMe()"
>
加载更多
</button>
<script>
var btn = document.getElementById("btn");
btn.onclick = function () {
console.log("发送请求加载更多数据....");
console.log("加载完成");
};
</script>
</body>
可以发现如果不加以限制的话,快速点击,也会发出很多请求
解决
提前准备一个开关变量,当第一次点击发送请求时,允许发送,但是要把开关关闭,点击不再发送请求,直到请求回来后把开关打开,这次又能重新发送请求。
<body style="height: 2000px">
<button
id="btn"
style="position: fixed; right: 0; bottom: 200px"
onclick="clickMe()"
>
加载更多
</button>
<script>
var canClick = true;
var btn = document.getElementById("btn");
btn.onclick = function () {
// 如果当前开关开着说明可以单击
if (canClick) {
// 先关闭开关
canClick = false; // 再发送请求
console.log("发送请求加载更多数据....");
// setTimeout(function () {
console.log("加载完成"); // 在请求的回调函数结尾重新打开开关允许再次单击发送请求
canClick = true;
// }, 3000);
} else {
}
};
</script>
</body>