节流
有点类似于技能冷却中,使得一定时间内只触发一次函数,是通过判断是否到达一定时间来触发函数。按照一段时间的时间间隔来进行触发函数。
const throttle = (func, delay) => {
let timer = 0
return (...args) => {
if(timer) {return} // 当前有任务,直接返回
func.call(undefined, ...args)
timer = setTimeout(()=> {
timer = 0
}, delay)
}
}
const f1 = throttle(()=> {console.log('hello')}, 5000)
f1() // 打印 hello
f1() // 技能冷却中
// setInterval(()=> f1(), 500)
适用场景:
- 拖拽:固定时间内只执行一次,防止超高频次触发位置变动。
DOM元素的拖拽功能实现(mousemove) - 滚动:监听滚动
scroll事件判断是否到页面底部自动加载更多 - 动画:避免短时间内多次触发动画引起性能问题
防抖
有点类似于回城被打断,将触发非常频繁的事件合并为一次去执行,在指定时间内只执行一次回调,如果在指定时间内又触发了,则回调的执行时间会基于此时刻重新开始计时。
const debounce = (func, wait = 50) => {
// func 是用户传入需要防抖的函数
// wait是等待时间,默认设为50ms
let timer = null
return (...args)=> {
if(timer !== null){
clearTimeout(timer) // 打断回城
}
// 重新回城
timer = setTimeout(()=> {
func.call(undefined, ...args) // 回调后调用 fn
}, wait)
}
}
const f1 = debounce(()=> {console.log('hello')}, 500)
f1() // 绑定到某一个事件上
具体实现,在Vue3演练场中尝试。
<script setup>
const debounce = (func, wait = 50) => {
// func 是用户传入需要防抖的函数
// wait是等待时间,默认设为50ms
let timer = null
return (...args)=> {
if(timer !== null){
clearTimeout(timer) // 打断回城
}
// 重新回城
timer = setTimeout(()=> {
func.call(undefined, ...args) // 回调后调用 fn
}, wait)
}
}
const f1 = debounce(()=> {console.log('hello')}, 500)
</script>
<template>
<button @click="f1">点我</button>
</template>
适用场景:
- 文本输入的验证,连续输入文字后发送 AJAX 请求进行验证,验证一次就好
- 按钮提交:防止多次提交按钮,只执行最后提交的一次
- 服务端验证:表单验证需要服务端配合,只执行一段连续的输入事件的最后一次
总结
防抖:限制执行次数,多次密集的触发只执行一次;
节流: 限制执行的频率,按照一个的时间间隔有节奏的执行。
防抖是将多次执行变为最后一次执行,节流是将多次执行变成每隔一段时间执行。