zoukankan      html  css  js  c++  java
  • 防抖和节流

    使用场景

    有时,我们会绑定一些持续触发的事件,如: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)
        }
      }
    }
  • 相关阅读:
    grails How to check if element in groovy array/hash/collection/list? Stack Overflow
    慧忠里自提点
    GroovyQ | 关注Groovy社区动态,分享Groovy开发经验。
    strupr strlwr
    Faqseafilevssvn seafile
    C++ STL下载和安装
    Emacs中学习gdb调试
    Readlineselect
    Diskfileio GongGeng
    Achieving Groovylike Fluency in Java with Google Collections | The Kaptain on ... stuff
  • 原文地址:https://www.cnblogs.com/00feixi/p/11973231.html
Copyright © 2011-2022 走看看