手写防抖和节流
对节流与防抖的理解
使用防抖和节流的目的:
为了避免频繁触发回调,导致大量的计算和异步请求,而造成的性能或者卡顿问题
防抖
概念
函数防抖是指在事件被触发 n 秒后再执行回调,如果在这 n 秒内事件又被触发,则重新计时。
这可以使用在一些点击请求的事件上,避免因为用户的多次点击向后端发送多次请求。
应用场景
- 按钮提交场景:防⽌多次提交按钮,只执⾏最后提交的⼀次
- 服务端验证场景:表单验证需要服务端配合,只执⾏⼀段连续的输⼊事件的最后⼀次
- mousemove 鼠标滑动事件
节流
概念
函数节流是指规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。
节流可以使用在 scroll 函数的事件监听上,通过事件节流来降低事件调用的频率。
应用场景
- 用户在输入框不断输入值时,每隔规定的时间来读取一次数据input(单位时间内只触发一次)
- 轮播图在播放过程中,用户不断点击切换没有效果,只能在规定时间后才可以进行点击
- 避免短时间内多次触发动画引起性能问题
手写防抖
两种类型
立即执行:即多次触发事件,第一次会立即执行函数,之后在设定wait事件内触犯的事件无效,不会执行。
非立即执行函数: 多次触发事件,只会在最后一次触发事件后等待设定的wait时间结束时执行一次。
// 首次不立即执行 function debounce(fun, delay) { let timer = null; return function () { const context = this args = [...arguments] if (timer) { clearTimeout(timer) timer = null } timer = setTimeout(() => { fun.apply(context, args) }, delay) } } // Select去服务端动态搜索功能,需要立即执行,给用户展示 // 默认的m条数据,等到用户手动输入停止触发n秒后,再重新执行 function debounce(fun, delay, immediate) { let timer = null; let localImmediate = immediate; return function () { const context = this args = [...arguments] if (localImmediate) { localImmediate = false; fun.apply(context, args) } clearTimeout(timer) timer = setTimeout(() => { fun.apply(context, args) }, delay) } }
手写节流
function throttle(fun, delay) { let preTime = Date.now() return function () { const context = this args = [...arguments] nowTime = Date.now() if (nowTime - preTime >= delay) { preTime = Date.now() return fun.apply(context, args) } } }
参考文章:

浙公网安备 33010602011771号