防抖 与 节流
大厂面试题分享 面试题库
前后端面试题库 (面试必备) 推荐:★★★★★
地址:前端面试题库 web前端面试题库 VS java后端面试题库大全
前言
防抖和节流作为很多大厂的经典面试题,问倒了许多小伙伴,其实它们的原理和实现都没有那么难,这篇文章带你轻松搞定!
正文
一、定义
防抖:在
触发一次函数后
的规定时间内
没有再次
触发才执行
节流:
连续触发
事件,在规定时间内
只执行一次
来个经典的比喻,帮助你更好理解:
我们把电梯完成**一次运送**,类比为一次函数的**执行和响应**。 假设电梯有两种运行策略** debounce **和** throttle **,超时设定为15秒, 不考虑容量限制。 **防抖**:电梯第一个人进来后, 等待15秒。如果过程中又有人进来,15秒等待重新计时, 直到15秒后开始运送。 **节流**:电梯第一个人进来后,15秒后准时运送一次。
二、实现
1. 防抖的实现
实现: 实现前端一个按钮,当你频繁点击
时,并不会
发送请求,只有当你在规定时间内没有再点击
时,才会执行函数。如果停止点击但是在规定时间内再点击
,会重新触发计时
。
思路:在一段连续操作结束后,处理回调,利用clearTimeout
和setTimeout
实现。
前端代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="./debounce.js"></script> <title>Document</title> </head> <body> <button id="btn">0<button> <!-- 按钮实现 --> <script src="./debounce.js"></script> <!-- 引入防抖js文件 --> <script> let count=0 <!-- 记录点击次数 --> let btn=document.getElementById("btn") <!-- 获取DOM结构 --> function add(e){ <!-- 实现按钮点击次数递增 --> console.log(this); this.innerHTML=count++ return 123 } btn.addEventListener('click',debounce(add,1000)) <!-- 监听按钮点击事件 --> </script> </body> </html>
js代码: (这里涉及到了闭包及this的原理)
function debounce(func,wait){ let timeout,result return function(){ let args=[...arguments] //获取事件参数 clearTimeout(timeout) //清除上一次的定时器 timeout= setTimeout(()=>{ result=func.apply(this,args) //this显示绑定 },wait)//定时器会修改this指向 定时器词法环境大多数都是window return result }
2. 节流的实现
实现: 实现前端一个按钮,在一个规定时间
内,只能触发一次
函数。如果这个时间内按钮多次
点击,只有一次
生效。
思路:使用时间戳
的写法实现。
前端代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="./throttle.js"></script> <title>Document</title> </head> <body> <button id="btn">0</button> <script> let count=0 let btn=document.getElementById("btn") function add(){ console.log(count); btn.innerHTML=count++ return 123 } btn.addEventListener('click',throttle(add,1000)) </script> </body> </html>
js代码: (这里涉及到了闭包及this的原理)
function throttle(func, wait) { let preTime = 0 //上一次的时间 return function () { let args = [...arguments] //获取事件参数 let now = +new Date() //时间戳 精准到秒 if (now - preTime > wait) { //点击第二次的时候判断时间有没有到 func.apply(this, args) preTime = now } } }
三、应用场景
防抖:
- 搜索框搜索输入。只需用户最后一次输入完,再发送请求
节流:
- 滚动加载,加载更多或滚到底部监听
总结
个人理解,防抖就是“一直抖”(频繁触发事件),直到停下来了才执行最后那一次触发;节流就是按照规定时间间隔来,这个规定时间内只执行一次。