防抖和节流的实现方法

防抖(debounce)

案例:当用户多次点击一个按钮时,会重复执行事件造成性能浪费,比如多次点击发送网络请求。防抖的目的就是当多次触发点击事件时,只有当用户超过一段时间(delay)没有点击时,才会执行一次事件

1. 延迟执行版本

  • 如果timer计时器已经存在,则清除。
  • 然后再重新开启一个计时器,如果超过一段时间(delay)该计时器仍然存在,则执行需要的函数func()
function debounceDelay(func, delay = 1000) {
    let timer = null
    return function () {
        // 延迟执行版本
        if (timer) {
            clearTimeout(timer)
        }
        timer = setTimeout(() => {
            // 通过apply改变this指向,及参数传递
            func.apply(this, arguments)
        }, delay);

    }
}

2. 立即执行版本

  • 第一次点击,则立即执行func()
  • 然后开启一个计时器,使timer不等于null来保证在一段时间内,无法执行函数
  • 用户多次点击则阻止函数执行,并清除计时器,重新开启一个新的保护时间的计时器
  • 延迟时间过去后,timer被为null,func()失去保护
function debounceImmed(func, delay = 1000) {
    let timer = null
    return function () {

        // 立即执行版本
        if (timer === null) {
            func.apply(this, arguments)
        }else if (timer) {
            clearTimeout(timer)
        }

        timer = setTimeout(() => {
            timer = null
            console.log("超过时间没触发,timer为null");
        }, delay);

    }
}

节流throttle

案例:浏览器的滚动事件,当用户滚动一段距离,此时滚动事件可能已经触发了几百次。节流就是为了当用户多次触发事件时,每隔一段时间(wait)内,只执行一次函数func()

1. 时间戳版本

  • 初始化上一次执行时间previous为0
  • 每次触发事件时,now记录当前触发的时间
  • 如果(当前触发时间now - 上一次触发时间previous) > 间隔时间wait,则允许执行函数func()。否则不允许
  • 然后记录已经执行的时间到previous
function throttle(func, wait = 1000) {
    let previous = 0;
    return function() {
        let now = Date.now();
        if (now - previous > wait) {
            func.apply(this, arguments);
            // 执行func后更新前一个时间戳
            previous = now;
        }
    }
}

2. 定时器版本

  • 如果当前不存在保护计时器,则执行函数func(),并开启保护计时器,
  • 当用户还在触发事件时,如果保护计时器timer存在,则不允许执行
  • 超过间隔时间(wait),此时timer失效变为null,失去保护
function throttle(func, wait) {
    let timer = null;
    return function () {

        if (timer === null) {
            timer = setTimeout(() => {
                func.apply(this, arguments)
                timer = null;
            }, wait)
        }

    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容