一、节流
高频率的函数执行会给浏览器和服务器太大压力,设置一个间隔时间可以优化执行频率,记录上一次(初始)函数执行的时间,与此次执行时间比较;如果这个差值在设置的间隔时间内则定时执行,否则立即执行;如果在这个间隔时间内反复触发函数则无视。
实现
// 节流
function throttle (fn, wait) {
let timeout = null
let previous = 0
return function () {
const [content, args] = [this, arguments]
const now = Date.now()
// 定时器的延缓执行时间
const remain = previous + wait - now
// remain <= 0 首次执行、到了或超过间隔时间,执行函数
// remain > wait 强制修改了系统时间
if (remain <= 0 || remain > wait) {
if (timeout) {
clearTimeout(timeout)
timeout = null
}
fn.apply(content, args)
previous = now
} else if (!timeout) {
// remain > 0 && remain <= wait
// 事件触发在等待时间之内
timeout = setTimeout(() => {
timeout = null
fn.apply(content, args)
}, remain)
} else {
console.log('节流!')
}
}
}
// 测试
document.onclick = throttle(() => {console.log('打印!')}, 1000)
二、去抖
连续执行的函数调用只执行一次,防止大量的 DOM 操作。首次调用函数时设置一个延时执行定时器,在这个定时器未生效之前无视其他函数执行,执行完之后再清除定时器标记等待下次设置。
实现
// 去抖
function debounce (fn, wait) {
// 设置定时器 handle
let timeout = null
return function () {
const [content, args] = [this, arguments]
// 未设置定时器进入延时执行
if (!timeout) {
timeout = setTimeout(() => {
timeout = null
fn.apply(content, args)
}, wait)
} else {
console.log('去抖!')
}
}
}
// 测试
document.onclick = debounce(() => {console.log('打印!')}, 1000)