前言
函数节流: 指定时间间隔内只会执行一次任务;
函数防抖: 任务频繁触发的情况下,只有任务触发的间隔超过指定间隔的时候,任务才会执行;
场景:
比如连续输入文字后发送 AJAX 请求进行验证,此时需要使用函数节流,只执行一次
。
如果是判断浏览器窗口resize时,每次resize都调用处理函数,又很浪费浏览器性能。此时应该采用函数防抖,每隔一段时间执行一次
。
函数节流throttle
规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。通俗来讲,就是在delay毫秒的时间内,函数只会触发一次。两次触发时间的间隔一定大于delay毫秒
使用场景:鼠标连续多次click事件,mousemove 事件,监听滚动事件,比如是否滑到底部自动加载更多等等...
// 节流函数1
function throttle(fn, delay) {
let canRun = true;
return function () {
if (!canRun) return;
canRun = false;
let context = this;
setTimeout(function () {
fn.apply(context, arguments)
canRun = true;
}, delay)
}
}
// 节流函数2
function throttle2(fn, delay) {
let lastTime = 0;
return function () {
let nowTime = new Date().getTime();
if(nowTime - lastTime > delay){
fn.call(this)
lastTime = nowTime
}
}
}
// 应用
document.addEventListener('scroll', throttle(function(){
console.log("test");
}, 300));
在此场景下,每隔一段时间,固定间隔执行一次。
函数防抖debounce
需要一个延时器来辅助实现,延迟执行需要执行的代码,如 果方法多次触发,把上次记录的延迟执行代码用 cleartimeout 清除掉, 重新开始,如果计时完毕,没有方法来访问触发,则执行代码
使用场景:以百度输入框例,比如你要查询XXx,想实现输完了XXx之后,再进行搜索请求,这样可以有效减少请求次数,节约请求资源。
document.addEventListener('scroll', debounce(function () {
console.log("test");
}, 300))
//防抖
function debounce(fn, delay) {
var timer = null;
return function () {
clearTimeout(timer)
var context = this;
timer = setTimeout(function () {
fn.call(context)
}, delay)
}
}
在此场景下如果一直滚动页面,定时器会一直被清理,只有当停止后,才会执行。