节流 (throttle)与 防抖 (debounce)都是为了下降调用频率的一种方式。html
相同点都是须要设置一个回调函数及周期时间,区别在于:react
防抖是在中止触发后的100ms,执行一次(在此时间段内,只要不中止触发,理论上就永远不会触发回调)git
节流是在不断的触发过程当中,每隔100ms就执行一次。github
下面简单画下流程图浏览器
在高频触发回调函数时,节流操做使回调函数在每隔一段时间按期执行一次,时间间隔内再触发,不会从新执行。markdown
核心在于让一个函数不要执行的太频繁,减小一些过快的操做。less
相似于技能冷却时间 ⏱ide
/** * 节流 * @param func * @param wait */
function throttle(func: Function, wait: number) {
let timer: number = 0;
return (...args) => {
if (timer) { return }
timer = window.setTimeout(() => {
func(...args)
timer = 0
}, wait)
}
}
复制代码
在高频触发回调函数时,防抖操做使回调函数在必定时间间隔内,再次触发会清空定时器,并从新计时;计时结束后输出一次结果。函数
核心在于,在短期内大量触发同一事件时,只会执行一次回调函数。避免把一次事件误认为屡次。oop
/** * 防抖 * @param func * @param wait */
function debounce(func: ()=>void, wait: number) {
let timer: number = 0
return (...args) => {
clearTimeout(timer)
timer = window.setTimeout(() => {
func(...args)
timer = 0; // 必须么??
}, wait)
}
}
复制代码
tips: 注意 args 剩余参数的传递,不然执行回调函数时参数将丢失。
🌰 栗子
// 监听页面滚动条位置
const handleScrollTop = () => {
const scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
console.log('滚动条位置:' + scrollTop);
}
// 防抖:在中止滚动100ms后,才会输出滚动条位置
window.onscroll = debounce(handleScrollTop,100)
// 节流:每隔100ms都会输出一次滚动条位置
window.onscroll = throttle(showTop,100)
复制代码
节流、防抖有时用哪一个均可以,好比监听页面滚动,能够节流(每一个一段时间出发一次回调),也能够防抖(用户当前此次滚动结束出发,继续滚动等待下一次触发)
须要注意调用节流/防抖函数位置,在组件初始化时就绑定节流/防抖事件,不然回调函数不会被触发。
constructor(props: any) {
super(props);
// 注意在此绑定!!
this.handleScroll = throttle(this.handleScroll, 100)
}
复制代码
参考