throttle的前世今生,以及在vue中如何使用?

516 阅读2分钟

一、什么是函数节流(throttle)

概念:限制一个函数在一定时间内只能执行一次。

背景: 在前端开发中,有时会为页面绑定resize事件,或者为一个页面元素绑定拖拽事件(其核心就是绑定mousemove),这种事件有一个特点,就是用户不必特地捣乱,他在一个正常的操作中,都有可能在一个短的时间内触发非常多次事件绑定程序。

而DOM操作时很消耗性能的,这个时候,如果你为这些事件绑定一些操作DOM节点的操作的话,那就会引发大量的计算,在用户看来,页面可能就一时间没有响应,这个页面一下子变卡了变慢了。甚至在IE下,如果你绑定的resize事件进行较多DOM操作,其高频率可能直接就使得浏览器崩溃。

要点:“函数节流”的要点在于,在  一定时间 之内,限制  一个动作 只  执行一次

二、函数节流如何解决上述问题

主要实现思路就是通过   setTimeout 定时器,通过设置延时时间,在第一次调用时,创建定时器,先设定一个变量true,写入需要执行的函数。第二次执行这个函数时,会判断变量是否true,是则返回。当第一次的定时器执行完函数最后会设定变量为false。那么下次判断变量时则为false,函数会依次运行。目的在于在一定的时间内,保证多次函数的请求只执行最后一次调用。

三、原生代码实现

// 定时器方案
function throttle(fn,wait){
    var timer = null;
    return function(){
        var context = this;
        var args = arguments;
        if(!timer){
            timer = setTimeout(function(){
                fn.apply(context,args);
                timer = null;
            },wait)
        }
    }
}
    
function handle(){
    console.log(Math.random());
}
    
window.addEventListener("mousemove",throttle(handle,1000));

四、vue中使用loash的代码实现方式

//伪代码
import { includes,throttle} from 'lodash';//引入lodash 的节流方法
.
.
.

export default {
  name:"test",
  data(){
    return {
      ...
    }
  },
  directives:{//自定义方法
      hover(el,obj,content){
        el.addEventListener('drag',function(e){//在拖动的过程中一直调用testFn方法
          content.context.testFn(e,valid,temp,item,content)
        });
      },
  },
  methods:{
    testHandler(e,valid,temp,item,content){//没有使用的方法
        //do something
    },
    testFn:throttle(function(...args){//每200毫秒调用一次
      this.testHandler(...args)
    },200), 
  },
  created(){
  }
.
.
.
};