咱们在开发的过程当中,常常会有这样一种状况,函数被频繁的调用,若是这个函数执行了某些dom操做的话,那么浏览器将会很是耗费性能,从而影响用户体验javascript
经过设置定时器保证一段时间内事件回调函数只能执行一次的作法在javascript业界有一个专业的术语称谓——防抖!java
它的原理其实很简单:1 用闭包实现一个timer变量,用来保存上一次调用函数的定时器id;2 咱们不是直接调用函数,而是中间须要一个间隔,若是两次调用之间的时间差小于咱们传递的值,那么清空上一次的调用值;3 咱们每一次调用的时候都清除一下上一次的调用定时器id,这样就保证了,若是间隔时间小于咱们设置的值,那么上一次函数必定不会调用,从而达到了下降调用频率的效果。web
function debounce(fn,time){ //设置定时器 let timer; return function(...args){ //清空上一次的定时器 clearTimeout(timer); //获取执行环境的上下文 let context = this; let _arguments = args; timer = setTimeout(()=>{ fn.apply(context,_arguments); },time); }; };
函数节流(throttle):当持续触发事件时,保证必定时间段内只调用一次事件处理函数。
主要有两种方式实现:浏览器
方法一:时间差,原理无非就是两次调用之间的时间差小于设置时,那么不调用,反之调用。代码以下:闭包
function ttrottle(fn,time){ //上一次调用时间 let lastInvokeTime = new Date().getTime(); //当前调用时间 let currentInvokeTime; return function(...args){ currentInvokeTime = new Date().getTime(); if(currentInvokeTime - lastInvokeTime <= time)return; let context = this; let _arguments = args; lastInvokeTime = currentInvokeTime; fn.apply(context,_arguments); }; };
方法二:定时器实现,原理就是设置时间间隔,若是达不到时间间隔,就清除上一次调用回调定时器id。代码以下: app
function ttrottle(fn,time){ let isNeedInvoke = true; return function(...args){ if(!isNeedInvoke)return; let context = this; let _arguments = args; isNeedInvoke = false; setTimeout(()=>{ fn.apply(context,_arguments); isNeedInvoke = true; },time); }; };