防抖函数
事件被触发时,在n秒后执行函数,在n秒内多次触发事件,则重新开始计时
利用定时器来实现,在n秒内多次触发,则先清除定时器,从新计时
1 // 定义一个请求函数 2 function request(val) { 3 console.log("request: " + val); 4 } 5 6 // 定义一个防抖函数 7 function debounce(fn, delay) { 8 let timeout; 9 return function(){ 10 clearTimeout(timeout) 11 timeout = setTimeout(()=>{ 12 fn.apply(this, arguments) 13 },delay) 14 } 15 } 16 17 let inputEl = document.getElementById("input"); 18 19 let debounceInput = debounce(request, 500) 20 21 inputEl.addEventListener("keyup", function (e) { 22 debounceInput(e.target.value); 23 });
节流函数
在规定的单位时间段内,函数只能执行一次,在单位时间内多少触发,则只有一次有效
定时器来实现
当一个定时器执行,就会生成一个定时器id,当这个id存在就说明在单位时间内函数只执行了一次。
// 定义一个请求函数 function request(val) { console.log("request: " + val); } // 定义一个节流函数 function throttle(fn, delay) { let timer; return function(){ if(!timer) { fn.apply(this, arguments) timer = setTimeout(()=>{ clearTimeout(timer) timer = null },delay) } } } let inputEl = document.getElementById("input"); let throttleInput = throttle(request, 500) inputEl.addEventListener("keyup", function (e) { throttleInput(e.target.value); });
实现方法2 /** * 节流,每隔N秒只执行一次函数 * @param {*} fun 调用的函数 * @param {*} wait 间隔时间 */ function throttle(fun, wait) { let timeout, context; return function (...args) { context = this; if (!timeout) { timeout = setTimeout(() => { fun.apply(context, args); timeout = null; }, wait); } }; }
总结
- 防抖函数和节流函数都是用于控制函数调用频率,但是两者实现原理不同
- 防抖函数是在触发事件的单位时间后执行一次函数,在单位时间内多次触发不执行函数,重新计时
- 节流函数是单位时间内只执行一次函数,多次触发也只有一次有效
适用场景
防抖
- 搜索输入框搜索内容,用户在不断的输入的时候,用防抖来节约请求资源
- 不断的触发window的resize事件,不断的改变窗口大小,利用防抖函数来只执行一次
节流
- 鼠标不断的点击,用节流来限制只在规定的单位时间内执行一次函数
- 滚轮事件, 不断的往下滚轮,比如滚动到底部加载数据