之前准备面试、看面经的时候,总会在内心骂,怎么这么多沙雕题目,这不是特地为难我胖虎吗
参加工做一年多了,发现不少面试题在工做中真的会明的暗的碰到。
能让我等菜鸟提早知道这么多概念,为咱们指明debbug的方向,真是煞费了前人的一番苦心呀。css
这两天遇到一个bug正好是利用节流的思想解决的,趁此机会正好把我对防抖节流思想的理解和应用整理一下,写出了,但愿能在工做和面试中帮到你们html
防抖(debounce)和节流(throttle)很容易搞混,定义极其晦涩。所以咱们先从应用场景入手vue
在输入文字的时候咱们进行某些处理,若是直接绑定处理函数,则每次输入都会处理一次,形成性能浪费,咱们实际但愿的是用户输入完了或者暂时输入完了咱们再去处理,因此须要给定一个延迟时间,而后若是一直输入咱们一律不断去刷新这个延迟时间,直到中止输入了再延迟处理ios
debounce函数挺简单的,就是一个延迟执行,和刷新延迟功能,用Js的定时器和清除定时器很容易搞定,写个超级简单的版本面试
未防抖:<input type="text" oninput="handleInput()"> 防抖处理后:<input type="text" oninput="debounce(handleInput,300)()">
function debounce (fn,delay){ return function () { fn.tid && clearTimeout(fn.tid) fn.tid=setTimeout(fn,delay) } }
登陆按钮,用户登陆的时候点一下,假设报错,帐号密码错误
若是用户手贱,一直狂点,会一直出提示,须要优化一下,先看下效果未使用节流:重复动做忒多
未使用节流:动做必定时间内只执行一次
element-ui
怎么实现throttle(fn,delay)这个函数呢,单位时间内只能执行一次,换句话说当前执行的时候与前一次执行时间差必须大于delay才让执行
咱们要保存上一次执行时间,咋保存呀?经过闭包
写个超级简单的,网上看了其余几我的的,好像和我不太同样if后面还跟了个else,使单位时间后还会执行一次,这个就看我的需求啦哈哈哈,主体逻辑绝壁是我这个,你们放心大胆抄,原创
axios
throttle(fn,interval){ let lastTime = new Date().getTime()//闭包保存上一次时间,注意这个函数执行的时候LastTime就存在了,因此通常点击的时候再触发,fn基本会执行,也就是先执行一次,而后单位时间执行一次 return function () { let currentTime = new Date().getTime() if(currentTime-lastTime>interval){ fn() lastTime = currentTime } } }
完整代码后端
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"> <!-- 引入组件库 --> <script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/element-ui/lib/index.js"></script> </head> <body> <div id="app"> 未节流:<el-button @click="handleLogin">login</el-button><br/><br/><br/> 节流:<el-button @click="throttleHandleLogin">login</el-button> </div> <script > new Vue({ el: '#app', data: function(){ return { throttleHandleLogin: this.throttle(this.handleLogin,2000) } }, methods: { handleLogin(){ this.$message({message:'帐号密码错误',type:'error'}) }, throttle(fn,interval){ let lastTime = new Date().getTime() return function () { let currentTime = new Date().getTime() if(currentTime-lastTime>interval){ fn() lastTime = currentTime } } } } }) </script> </body> </html>
问你们一个问题,为何我会把throttleHandleLogin写在data里面?写在methods里面行不行?想知道答案的点赞留言
闭包
看起来防抖节流都是解决动做重复触发产生的性能问题的,可是他们的原理是不一样的
debounce 是延迟执行,刷新延迟(理论上若是我一直动是否是能够一直不执行?)
throttle 是马上执行,间隔执行,(单位时间确定得执行,应该不会有人会无聊到把间隔时间设置为无限长吧)
因此区别能够记成,当动做一直持续下去,函数会不会执行。debounce不会,throttle会app
仍是记不住区别的记使用场景吧
如今运用咱们所学解决上个星期我遇到的一个场景
我在axios里面有个响应拦截器,遇到后端返回的状态码为xx(没有权限)会跳到登陆页,报错没有权限
可是有个问题,在某些页面我会不止发一个请求,每一个请求都会受到没有权限的响应引发报错,因此跳到登陆页我会受到N个没有权限的提示
怎么作?用debounce仍是throttle?
我用的throttle解决的,3秒内若是是权限问题,只让报一次错
//fn是权限错误的相关逻辑 const throttlefn = throttle(fn,3000,{trailing:false}) service.interceptors.response.use( async res => { if (!res.data) return null const { data: { msg, status } } = res switch (status) { case OK:... case NOT_LOGIN:case LoginFailed:case InvalidRole:case INVALID_PWD: throttlefn(msg) break case NONE_DATA:... default:... } },...)
今天关于节流防抖的优化就分享到这了。因为技术有限,若是阅读中发现有什么错误,请在留言指出 若是你以为本文对你有很大的帮助,求点赞,求收藏,求打赏,大家的支持是做者写做的最大动力!