防抖和节流
使用场景
有时,我们会绑定一些持续触发的事件,如:resize、scroll、mousemove等,但是我们并不希望在事件持续触发的过程中那么频繁的去执行函数。通常情况下怎么去解决呢?一般来讲,防抖和节流是比较好的解决方案。
下面,我就已在vue中的input函数为例,讲解一下防抖和节流。
防抖
所谓防抖,就是指触发事件后在n秒内,函数只能执行一次,如果在n秒内又触发了事件,则会重新计算函数执行的时间。
其实防抖函数并不难写,下面这就是一个最初级的防抖函数:
<template>
  <div id="app">
    <el-input @input.native="inputFn" v-model='msg'></el-input>
  </div>
</template>
<script>
export default {
  components: {},
  data(){
    return{
      msg: '',
      timeout: ''
    }
  },
  methods: {
    // 最初级的防抖
    inputFn(e){
      if(this.timeout) clearTimeout(this.timeout)
      this.timeout = setTimeout(() => {
        console.log('执行函数')
      }, 3000)
    }
  }
}
</script>
接下来,我们利用闭包改造一下这个防抖函数,不要将timeout定义在函数外面了
<template>
  <div id="app">
    <el-input @input.native="inputFn" v-model='msg'></el-input>
  </div>
</template>
<script>
export default {
  components: {},
  data(){
    return{
      msg: '',
      timeout: '',
      delay: ''
    }
  },
  mounted(){
    // 初始化防抖函数
    this.delay = this.debounceFun(this.requestFun, 3000)
  },
  methods: {
    inputFn(e){
      this.delay('传入的参数')
    },
    // 第二版,非立即执行
    // 非立即执行版的意思是触发事件后函数不会立即执行,而是在 n 秒后执行,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
    debounceFun(func, wait){
      let timeout = ''
      return function(){
        let context = this
        let args = arguments
        if(timeout) clearTimeout(timeout)
        timeout = setTimeout(() => {
          func.apply(context, args)
        }, wait)
      }
    },
    requestFun(data){
      console.log(data)
      console.log('执行函数')
    }
  }
}
</script>
这样,我们就把防抖函数写好了,是不是很简单
这面的这种是非立即执行版的,下面我们再来改造一下,实现一版立即执行版的防抖函数
立即执行版的意思是触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的效果。
// 第三版:立即执行 // 立即执行版的意思是触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的效果。 debounceFun(func, wait){ let timeout = '' return function(){ let context = this let args = arguments // 记录当前是否存在timeout,如果不存在,则说明是第一次 let isNow = !timeout if(timeout) clearTimeout(timeout) timeout = setTimeout(() => { func.apply(context, args) }, wait) // 如果不存在timeout,说明是第一次触发,则执行一次回调函数 if(isNow) func.apply(context, args) } }
下面,我们再来写一版立即执行和非立即执行的合并版
// 第四版 // 当immediate为true时,是立即执行版;当immediate为false时,是非立即执行版 debounceFun(func, wait, immediate){ let timeout = '' return function(){ let context = this let args = arguments // 记录当前是否存在timeout,如果不存在,则说明是第一次 let firstFlag = !timeout if(timeout) clearTimeout(timeout) timeout = setTimeout(() => { func.apply(context, args) }, wait) if(immediate){ // 如果不存在timeout,说明是第一次触发,则执行一次回调函数 firstFlag && func.apply(context, args) } } }
节流
所谓节流,就是指连续触发事件,但是在n秒钟只执行一次的函数。节流会稀释函数的执行频率
throttleFun(func, wait){ let timeout = '' return function(){ let context = this let args = arguments if(!timeout){ timeout = setTimeout(() => { timeout = null func.apply(context, args) }, wait) } } }
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号