实现debounce和throttle函数

Posted 任天镗

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现debounce和throttle函数相关的知识,希望对你有一定的参考价值。

1.该函数连续调用时,空闲时间必须大于或等于函数定义的wait时间,任务才会执行的函数叫防抖(debounce)函数
2.该函数连续调用时,每隔一段时间,至多执行一次任务的函数叫节流(throttle)函数。

这里模拟lodash的防抖函数 _.debounce(func, [wait=0], [options=]) ,先说下lodash防抖函数的入参options的配置项:

options.leading 与|或 options.trailing 决定延迟前后如何触发(注:是 先调用后等待 还是 先等待后调用)。 func 调用时会传入最后一次提供给 debounced(防抖动)函数 的参数。 后续调用的 debounced(防抖动)函数返回是最后一次 func 调用的结果。
注意: 如果 leading 和 trailing 选项为 true, 则 func 允许 trailing 方式调用的条件为: 在 wait 期间多次调用防抖方法。

简单点说lodash的防抖函数,当options.leading为true、options.trailing为false时,就要我们平时所需要使用的节流函数用法,当options.leading为false、options.trailing为true时就是我们平时所需要使用的防抖函数用法,本人自己模拟实现了一下,代码如下

/**
 * 
 * @param {function} func 需要执行的防抖函数
 * @param {number} wait 等待时间毫秒
 * @param {object} options {leading: 为true表示在等待时间开始前执行防抖函数,trailing: 为true表示在等待时间开始之后执行防抖函数}
 */
function debounce(func, wait = 500, options) {
    if (typeof func !== "function") throw new Error("func must be function");

    let timer = null;
    const {
        leading = false,
        trailing = true
    } = options || {}

    const res = function (...argus) {
        const self = this;

        if (!leading && trailing) {
            clearTimeout(timer);
            timer = setTimeout(() => {
                func.apply(self, argus);
                timer = null;
            }, wait)
        }

        if (leading){
            if (!timer) {
                func.apply(self, argus);
                timer = setTimeout(() => {
                    timer = null
                }, wait)
            } else {
                // 如果存在定时器,说明在wait时间段内执行过防抖函数
                if (trailing){
                    // 如果为true,则等待wait时间后执行防抖函数
                    clearTimeout(timer);
                    timer = setTimeout(() => {
                        func.apply(self, argus);
                        timer = null
                    }, wait)
                }
            }

        }
        
        // 设置防抖函数的后置取消功能
        res.cancel = function () {
            if (timer) {
                clearTimeout(timer);
                timer = null;
            }
        }

        // 设置防抖函数立即执行功能
        res.flush = function () {
            if (timer) {
                clearTimeout(timer);
                timer = null;
                func.apply(self, argus);
            }
        }
    }

    return res;
}

这里特别注意,本人编写的内置cancel、flush方法只对options.leading=false和options.trailing=true时有效,对于其他情况下暂时还没做逻辑判断处理,如各位小伙伴了解其它规则机制,可以给本人点意见,哈哈哈!

以上是关于实现debounce和throttle函数的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript函数节流(throttle)与函数去抖(debounce)

js 消抖(debounce)与节流(throttle)

vue 简单实现函数防抖(debounce)和节流(throttle)

lodash源码学习debounce,throttle

js 中的截流函数throttle 和 debounce

javascript函数节流(throttle)与函数去抖(debounce)