函数节流和函数防抖,两者都是优化高频率执行js代码的一种手段。
我们了解一下什么是防抖
函数防抖: 频繁触发的情况下,只有等待足够的空闲时间,才可以执行代码一次。
函数防抖的影响:防止函数在极短的时间内反复调用,造成资源的浪费。
就比如在页面上的某些事件触发频率非常高,比如滚动条滚动、窗口尺寸变化、鼠标移动等,如果我们需要注册这类事件,不得不考虑效率问题,又特别是事件处理中涉及到了大量的操作,让我们为之头痛。 当窗口尺寸发生变化时,哪怕只变化了一点点,都有可能造成成百上千次对处理函数的调用, 这对网页性能的影响是极其巨大的,很可能就造成页面的阻塞。于是,我们可以考虑,每次窗口尺寸变化、滚动条滚动、鼠标移动,不要立即执行相关操作,而是等一段时间,以窗口尺寸停止变化、滚动条不再滚动、鼠标不再移动为计时起点,一段时间后再去执行操作,就像电梯关门那样。
也就是说触发高频事件 N 秒后只会执行一次,如果 N 秒内事件再次触发,则会重新计时,重新开始计时。
// 简单版本
function debounce(func, wait) {
// 使用闭包来维护timer
var timeout = null;
return function () {
var context = this;
var args = arguments;
clearTimeout(timeout)
// 注册回调函数
timeout = setTimeout(function(){
func.apply(context, args)
}, wait);
}
}
function testout(e, content) {
console.log(e, content);
}
var fn = debounce(testout, 2000); // 防抖函数
document.onmousemove = function (e) {
fn(e, 'debounce'); // 给防抖函数传参
}
鼠标一直移动(一直在触发onmousemove里面的事件,但是有debounce约束),则不输出,若停止移动,则在间隔1S后输出一次(唯一的一次哦!!!))
setInterval(debounce(fn,500),1000) // 第一次在1500ms后触发打印,之后每1000ms触发一次
打印一次debounce
setInterval(debounce(fn,2000),1000) // 不会触发一次(我把函数防抖看出技能读条,如果读条没完成就用技能,便会失败而且重新读条)
应用场景有表单的防止重复提交,搜索框提示发送多次HTTP请求 有兴趣的可以输入的了解一下哦!
参考:JavaScript专题之跟着underscore学防抖
什么是节流
节流函数: 让一个函数无法在短时间内连续调用,只有当上一次函数执行后,过了规定的时间间隔,才能进行下一次该函数的调用。或者说你在操作的时候不会马上执行该函数,而是等你不操作的时候才会执行。 对于函数节流,有如下几个场景:
1. 游戏中的刷新率
2. DOM元素拖拽
3. Canvas画笔功能
函数节流
function throttle(fn, gapTime) {
let _lastTime = null;
return function () {
let _nowTime = + new Date()
if (_nowTime - _lastTime > gapTime || !_lastTime) {
fn();
_lastTime = _nowTime
}
}
}
let fn = ()=>{
console.log('boom')
}
setInterval(throttle(fn,1000),100)
每0.1s在任务队列中注册一个throttle函数,实现的一个简单的函数节流,结果却是一秒打出一次boom
小结::函数防抖和节流,都是控制事件触发频率的方法。