在一些少数情况下,函数的触发不是由用户直接控制的。在这些场景下,函数有可能被非常频繁地调用,而造成大的性能问题。下面将列举一些这样的场景。
- 出现场景
- window.onresize 事件
- mousemove 事件
原理
throttle 函数的原理是,首次调用立即执行, 后续调用放到定时器中, 延迟一段时间执行。 如果之前的延迟执行还没有完成,不重置定时器, 会忽略调用该函数的请求。
思想:每隔一段时间,只执行一次函数
实现
throttle 函数接受2个参数,第一个参数为需要被延迟执行的函数,第二个参数为延迟执行的时间
首次立即执行, 第二次开始使用定时器执行 fn 执行的函数 interval 延迟执行时间
/**
* @description 函数节流: 每隔一段时间,只执行一次函数
* @param { Function } fn 需要延迟执行的函数
* @param { Number } interval 延迟执行的时间,默认值500ms
*/
export function throttle(fn, interval = 500) {
// 记录定时器id
let timer = null
// 是否是第一次调用
let isFirstTime = true
return function () {
const args = arguments
const _me = this
// 第一次直接执行,改变标志,无需延迟
if (isFirstTime) {
fn.apply(_me, args)
return isFirstTime = false
}
// 不是第一次
// 存在定时器,前面的延迟操作没有完成,直接返回,拒绝调用请求
if (timer) {
return false
}
// 延迟执行
timer = setTimeout(() => {
clearTimeout(timer)
timer = null
fn.apply(_me, args)
}, interval)
}
}
- 使用
window.onresize = throttle(function () {
console.log(1);
}, 2000)
防抖和节流
区别在于,防抖每次触发事件都重置定时器,而节流在定时器到时间后再清空定时器