# JS的防抖(debounce)和节流(throttle)
# 防抖(debounce)
# 非立即执行版
非立即执行版指的是事件触发之后,若wait秒内又一直触发,则将重新计时,fn 回调函数将不会触发。
function debounce(fn, wait) {
let timer = null;
return function() {
// 上下文
const context = this;
// 参数(Array)
const args = arguments;
if (timer != null) {
clearTimeout(timer);
}
//
timer = setTimeout(function() {
fn.apply(context,args);
}, wait);
}
}
# 运用场景
- 输入框检索功能,若一直输入,则不去调用后端,等停止输入的 wait 毫秒后,才触发去调用后端接口。
- 窗口缩放(resize),等停止后再去处理其他事情。
- 表单验证,输入完后才进行校验。
# 立即执行版
立即执行版指的是事件触发后第一次马上执行,之后出若在wait秒内一直触发,则重新计时,直到wait秒后 fn 回调才会触发。
function debounce(fn, wait) {
let timer = null
return function() {
const context = this
const args = arguments
if (timer == null) {
fn.apply(context, args)
} else {
clearTimeout(timer)
}
timer = setTimeout(_ => {
timer = null
}, wait)
}
}
# 运用场景
- 按钮点击提交数据事件,第一次点击马上触发,后面连续点击将无效果;直到停止wait秒后再点击就会马上触发。
# 节流(throttle)
保证一定的时间内只触发一次事件
# 非立即执行版
function throttle(fn, wait) {
let timer = null
return function() {
const context = this
const args = arguments
if (!timer) {
timer = setTimeout(_ => {
fn.apply(context, args)
timer = null
}, wait)
}
}
}
# 立即执行版
function throttle(fn, wait) {
let timer = null
let startTime = Date.now()
return function() {
const context = this
const args = arguments
let curTime = Date.now()
if (timer) {
clearTimeout(timer)
}
// 剩余几秒
const diffTime = wait - (curTime - startTime)
if (diffTime <= 0) {
fn.apply(context, args)
startTime = Date.now()
} else {
// 过 剩余的几秒后执行
timer = setTimeout(_ => {
fn.apply(context, args)
startTime = Date.now()
}, diffTime)
}
}
}
# 应用场景
- 滚动条是否滑到底部,从而加载更多。