详谈js函数中的防抖和节流

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ws9029/article/details/88852307

其实很多同学对这两个的定义模糊不清,包括我之前学的时也感觉没什么区别!,当你深入研究下,其实两者的区别很大的。

1.节流

节流顾名思义就是节约流水(流量),流水于是我联想到水龙头,当你拧开水龙头(力度很大),水会很猛的往下喷出来,其实我们并不需要那么大的水流,我们可以把水龙头关小,让它一滴滴的往下流(当然没人会这么用,除非开关关不拢),这样就节约了流水,所谓节流也是一样的道理,当一个函数再不断的执行,我不需要它那么频繁的执行,就想鼠标mousemove事件,你一移动可能就执行了几十次,我只需要他执行一次,这时就用到了节流。节流的原理是通过判断是否到达一定时间来触发函数,使得再一定的时候内只触发一次。节流函数不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数。
1.时间戳写法:

    // 节流
var throttle = function (fn, delay) {
    //记录初始时间
    var start = Date.now();
    return function () {
        var context = this;
        var args = arguments;
        var now = Date.now();
        // 到了规定了时间执行函数
        if (now - start >= delay) {
            fn.apply(context, args);
            // 函数执行完成再次记录下一次的开始时间
            start = Date.now();
        }
    }
}
// 处理函数
var num = 0;

function handle() {
    num++;
    console.log(num)
}
// 鼠标移动事件
document.addEventListener('mousemove', throttle(handle, 3000));

2.定时器写法:

var throttle = function (fn, delay) {
     var timer = null;
     return function () {
         var content = this;
         var args = arguments;
         //当没有定时器就设置个定时器
         if (!timer) {
             timer = setTimeout(function () {
                 fn.apply(content, args);
                 // 还原timer值为下次做判断
                 timer = null;
             }, delay);

         };
     }
 }

 var num = 0;

 function handle() {
     num++;
     console.log(num)
 }
 document.addEventListener('mousemove', throttle(handle, 3000));
1.防抖

防抖我的理解就是多次触发函数,它相当把多次执行合并了,它只会最终执行一次,原理是规定在delay时间后触发函数时候后但是在delay时间内再次触发的话,这样会让定时器重置,这样它只能执行最后一次。用到的事件很多,比如输入文字keyup事件向后台发送请求,当每次键盘弹起都去向后台发送请求是不是很耗时,所以这里最好用防抖,当用户把文字全部输入完成就去发送请求。
下面模拟一个input事件

function debounce(fn, wait) {
    var timer = null;
    return function () {
        if (timer !== null) {
            clearTimeout(timer);
        }
        timer = setTimeout(fn, wait);
    }
}
// 处理函数
function handle() {
    console.log(input.value)
}
// 键盘弹起事件
var input = document.getElementById('input');
input.addEventListener('keyup', debounce(handle, 2000));

每当用户输入值之后会再2秒之后去执行handle函数,如果在2秒之内又有事件触发就会清楚之前的定时器,相当重置定时器,不断如此,直到没有事件再次触发,所以它只会执行最后一次函数。
实际开发过程中,要用节流和防抖要看需求而定,像浏览器滚动事件发送ajax请求,这样的肯定是用节流了,因为要每隔一段时间去发送ajax,而不是当你页面不在滚动了再去发送ajax。

猜你喜欢

转载自blog.csdn.net/ws9029/article/details/88852307