最近了解到这两个概念:防抖(debounce)和节流(thorttle),是因为想做一个图片的懒加载功能,就是滚动条往下拉的时候才加载新的图片,不由自主的想到监听滚动条事件,然后触发函数去加载新的图片资源。但是滚动条上下滚动的频率是非常高的,触发函数太过频繁会导致性能的损耗,查资料的时候就发现这两个概念的介绍,废话不多说,上介绍。
首先需要说明的是,防抖和节流这两概念都是为了解决频繁触发函数所来的一系列问题的,比如页面掉帧,卡顿,占用资源过多,浏览器崩溃等。
防抖(debounce)
在函数需要频繁触发时,只有当有足够空闲的时间时,才会触发一次。
这个概念我在看的时候有点模糊,什么叫有足够空闲时间呢,其实是等到某个高频率动作停止一段时间后,再执行由这个高频率动作触发的函数。如上面图片懒加载的例子,滑动滚动条一直不停滚动的时候,并不会马上触发请求图片的函数,而是在这个动作停下来足够多的时间(enough time pass)之后再执行一次。
实现,上代码:
function debounce(fn, delay) { var timer = null; return function() { if (timer) clearTimeout(timer); timer = setTimeout(function() { fn(); }, delay); } }
节流(thorttle)
预定一个函数只有在大于等于执行周期时才执行,周期内调用不执行。也就是隔一段固定的时间再执行一次。
例如单位时间之内(如1s)无论用户点多少次,都只算他点了一次,这就是节流的核心思想。
function throttle(handle, wait) { var lasttime = 0; return function(e) { var nowtime = new Date().getTime(); if(nowtime - lasttime > wait) { handle.apply(this, arguments); lasttime = nowtime; } } }
参数中 handle 为需要进行节流的方法,wait为等待时间。
因为我们需要实现在一定的等待时间wait内不能执行handle()方法,所以首先需要两个时间戳,一个记录第一次点击的时间lasttime,一个记录当前的时间nowtime,只有当 nowtime 与 lasttime 的时间差大于wait时,才会再次触发buy(),同时改变lasttime为新时间戳。
放在throttle()中就是首先记录初始时间为0,当第一次点击时,获得现在时间为nowtime,时间差大于wait,执行buy(),然后本次点击的时间就成了一个新的时间点,下次点击就需要和这次点击的时间进行判断,所以设置当前时间为初始时间,然后下次点击时继续判断。