节流和去抖的简单实现

一、节流

高频率的函数执行会给浏览器和服务器太大压力,设置一个间隔时间可以优化执行频率,记录上一次(初始)函数执行的时间,与此次执行时间比较;如果这个差值在设置的间隔时间内则定时执行,否则立即执行;如果在这个间隔时间内反复触发函数则无视。

实现

// 节流
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)

发表评论

电子邮件地址不会被公开。 必填项已用*标注