超级简单的防抖与节流

1340.640.jpg

前言

之前准备面试、看面经的时候,总会在内心骂,怎么这么多沙雕题目,这不是特地为难我胖虎吗
为难胖虎.jpeg
参加工做一年多了,发现不少面试题在工做中真的会明的暗的碰到。
能让我等菜鸟提早知道这么多概念,为咱们指明debbug的方向,真是煞费了前人的一番苦心呀。css

这两天遇到一个bug正好是利用节流的思想解决的,趁此机会正好把我对防抖节流思想的理解和应用整理一下,写出了,但愿能在工做和面试中帮到你们html

防抖(debounce)和节流(throttle)很容易搞混,定义极其晦涩。所以咱们先从应用场景入手vue

防抖(debounce)

应用场景

debounce.gif

在输入文字的时候咱们进行某些处理,若是直接绑定处理函数,则每次输入都会处理一次,形成性能浪费,咱们实际但愿的是用户输入完了或者暂时输入完了咱们再去处理,因此须要给定一个延迟时间,而后若是一直输入咱们一律不断去刷新这个延迟时间,直到中止输入了再延迟处理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)
    }
}

节流(throttle)

应用场景

登陆按钮,用户登陆的时候点一下,假设报错,帐号密码错误
若是用户手贱,一直狂点,会一直出提示,须要优化一下,先看下效果
未使用节流:重复动做忒多
未节流.gif
未使用节流:动做必定时间内只执行一次
节流.gifelement-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个没有权限的提示
初级知识盲区.png

怎么作?用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:...
    }
  },...)

结尾

今天关于节流防抖的优化就分享到这了。因为技术有限,若是阅读中发现有什么错误,请在留言指出 若是你以为本文对你有很大的帮助,求点赞,求收藏,求打赏,大家的支持是做者写做的最大动力!

相关文章
相关标签/搜索