资讯专栏INFORMATION COLUMN

JavaScript 函数节流 throttle 和防抖 debounce

mmy123456 / 1242人阅读

摘要:今天和别人聊到函数的节流和防抖,发现自己对这两个的区别很是模糊,遂小小实践一下,在此记录,希望对需要的人有所帮助。防抖实现顺利,但是两个节流方法的执行结果存在差异。

今天和别人聊到JavaScript函数的节流和防抖,发现自己对这两个的区别很是模糊,遂小小实践一下,在此记录,希望对需要的人有所帮助。

节流 - 频繁操作,间隔一定时间去做一件事

举例说明:假定时间间隔为 500ms,频繁不停的操作 2s,且每两次执行时间小于等于时间间隔 500ms,那么就会执行 4 次,也就是每隔 时间间隔 500ms 执行一次。

防抖 - 频繁操作,一定时间间隔内只执行最后一次操作

举例说明:假定时间间隔是 500ms,频繁不停的操作 5s,且每两次执行时间小于等于时间间隔 500ms,那么最后只执行了 1 次,也就是每一次执行时都结束了上一次的执行。

代码示例
    //节流方法 1
    function throttle1(method, duration){
        var prevTime = new Date();
        return function () {
            var context = this,
                currentTime = new Date(),
                resTime = currentTime - prevTime;
            //打印出本次调用方法和上次执行方法的时间差
            console.log("时间差"+resTime);
            //当本次调用距离上次执行方法的时间差大于等于要求时间间隔时,执行一次方法
            if(resTime >= duration){
                method.apply(context);
                //记录执行方法的时间
                prevTime = currentTime;
            }
        }
    }
    //节流方法 2
    function throttle2(method, duration){
        //当前时间间隔内是否有方法在执行(或者说方法的调用是否在进行)
        var runningFlag = false;
        return function (e) {
            // 判断当前是否有方法在执行,有,则什么都不做
            if (runningFlag) {
                return false;
            }
            //开始执行
            runningFlag = true;
            setTimeout(function(){
                method(e);
                //执行完毕,声明当前没有正在执行的方法,方便下一个时间间隔内的调用
                runningFlag = false;
            }, duration)
        }
    }
    //防抖
    function debounce(method, duration){
        var timer = null;
        return function(){
            var context = this,
                args = arguments;
            //在本次调用之前的一个间隔时间内,有方法在执行,则终止该方法的执行
            if(timer){
                clearTimeout(timer);
            }
            //开始执行本次调用
            timer = setTimeout(function(){
                method.apply(context, args);
            },duration);
        }
    }
    //模拟三个执行方法
    function jieliu1(){
        console.log("节流 1");
    }
    function jieliu2(){
        console.log("节流 2");
    }
    function fangdou(){
        console.log("防抖");
    }
    //持续执行时间
    var totalTime = 2000;

    var jieliuFn1 = throttle1(jieliu1,500);
    var jieliuFn2 = throttle2(jieliu2,500);
    var fangdouFn = debounce(fangdou,500);

    (function(duration){
        setInterval(function(){
            if( totalTime > 0 ){
                jieliuFn1();
                jieliuFn2();
                fangdouFn();
                totalTime -= duration;
            }
        },duration);
    })(100);
运行结果
时间差 100
时间差 201
时间差 303
时间差 401
时间差 504
节流 1
时间差 98
节流 2
时间差 199
时间差 300
时间差 396
时间差 496
时间差 597
节流 1
时间差 100
节流 2
时间差 203
时间差 299
时间差 402
时间差 500
节流 1
时间差 103
时间差 204
节流 2
时间差 303
时间差 400
节流 2
防抖
结论

由以上运行结果可以看出,节流1 出现了 3 次,节流2 出现了 4 次,防抖出现了 1 次。防抖实现顺利,但是两个节流方法的执行结果存在差异。
观察时间差可以看出,每次节流1 执行时,时间差并不会都是 500 整,也就是说,一共调用 2 秒时,节流1 并不能做到每隔 500 毫秒执行一次而共执行 4 次,第四次执行往往因为前面的 3 次执行的时间误差,而导致到达时间 2 秒时,最后一次的时间差无法达到 时间间隔 500ms 以上,以至于只能执行 3 次。

结论:当在一个大范围的时间内,比如两小时内,每几分钟执行一次,超过2小时则不再实行,推荐使用第一种节流方式,;如果仅仅要求间隔一定时间执行一次,推荐使用第二种节流方法;防止频繁操作,比如表单多次提交,推荐使用防抖。

如有问题,欢迎指正,谢谢!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/93789.html

相关文章

  • 关于js节流函数throttle防抖debounce

    摘要:主要实现在于通过异步操作的事件间隔,对于前后两次调用方法打时间进行比较,用清空定时器的操作实现多余调用操作的舍弃。 废话不多说,直奔主题。 什么是throttle和debounce? 这两个方法的主要目的多是用于性能优化。最常见的应用尝尽就是在通过监听resize、scroll、mouseover等事件时候的性能消耗。拿scroll来说,没有处理时滑动一次滚动条scroll事件会触发多...

    张红新 评论0 收藏0
  • 关于js节流函数throttle防抖debounce

    摘要:主要实现在于通过异步操作的事件间隔,对于前后两次调用方法打时间进行比较,用清空定时器的操作实现多余调用操作的舍弃。 废话不多说,直奔主题。 什么是throttle和debounce? 这两个方法的主要目的多是用于性能优化。最常见的应用尝尽就是在通过监听resize、scroll、mouseover等事件时候的性能消耗。拿scroll来说,没有处理时滑动一次滚动条scroll事件会触发多...

    lieeps 评论0 收藏0
  • 关于js节流函数throttle防抖debounce

    摘要:主要实现在于通过异步操作的事件间隔,对于前后两次调用方法打时间进行比较,用清空定时器的操作实现多余调用操作的舍弃。 废话不多说,直奔主题。 什么是throttle和debounce? 这两个方法的主要目的多是用于性能优化。最常见的应用尝尽就是在通过监听resize、scroll、mouseover等事件时候的性能消耗。拿scroll来说,没有处理时滑动一次滚动条scroll事件会触发多...

    shery 评论0 收藏0
  • 函数节流防抖

    摘要:当第二次调用该函数时,它会清除前一次的定时器并设置另一个。然而,如果前一个定时器尚未执行,其实就是将其替换为一个新的定时器,然后延迟一定时间再执行。参考文章函数节流与函数防抖函数节流和函数去抖应用场景辨析函数节流函数防抖实现原理分析 前言 事件的触发权很多时候都属于用户,有些情况下会产生问题: 向后台发送数据,用户频繁触发,对服务器造成压力 一些浏览器事件:window.onresi...

    didikee 评论0 收藏0
  • 函数节流防抖

    摘要:当第二次调用该函数时,它会清除前一次的定时器并设置另一个。然而,如果前一个定时器尚未执行,其实就是将其替换为一个新的定时器,然后延迟一定时间再执行。参考文章函数节流与函数防抖函数节流和函数去抖应用场景辨析函数节流函数防抖实现原理分析 前言 事件的触发权很多时候都属于用户,有些情况下会产生问题: 向后台发送数据,用户频繁触发,对服务器造成压力 一些浏览器事件:window.onresi...

    huaixiaoz 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<