节流防抖的使用

什么是防抖

当事件被触发后,延迟几秒后再执行回调,如果在这几秒内事件又被触发,则重新计时。如:游戏中的回城机制,中途打断后必须要重新回城,重新读条。

应用场景

用户在输入框中连续输入一串字符时,可以通过防抖策略,只有在输入完后,才执行查询的请求,这样可以有效减少次数,节约请求资源。
例如:实现输入框的防抖

//模拟ajax请求
function ajax(content) {
  console.log('ajax request ' + content);
}

let inputa = document.getElementById('unDebounce');

inputa.addEventListener('keyup', function (e) {
    ajax(e.target.value);
})

只要按下键盘,就会触发ajax请求。从资源上来说是很浪费的行为,实际应用中,用户是输出完整的字符后才会请求。可以进行优化:

function ajax(content) {
  console.log('ajax request ' + content);
}

function debounce(fun, delay) {
    return function (args) {
        let that = this;
        let _args = args;
        clearTimeout(fun.id);
        fun.id = setTimeout(function () {
            fun.call(that, _args);
        }, delay)
    }
}
    
let inputb = document.getElementById('debounce')

let debounceAjax = debounce(ajax, 500)

inputb.addEventListener('keyup', function (e) {
        debounceAjax(e.target.value)
    })

加入了防抖后,在频繁的输入时不会发送请求,只有当在指定间隔内没有输入时,才会执行函数。如果停止输入但是在指定间隔内又输入,会重新触发计时。

防抖代码

let timer; // 维护同一个timer
function debounce(fn, delay) {
    clearTimeout(timer);
    timer = setTimeout(function(){
        fn();
    }, delay);
}
// 用onmousemove测试一下防抖函数:
function testDebounce() {
    console.log('test');
}
document.onmousemove = () => {
    debounce(testDebounce, 1000);
}
----------------------------------------------
简化后代码:
function debounce(fn, delay) {
    let timer; // 维护一个 timer
    return function () {
        // let _this = this; // 取debounce执行作用域的this
        let args = arguments;
        if (timer) {
            clearTimeout(timer);
        }
        // timer = setTimeout(function () {
        //     fn.apply(_this, args); // 用apply指向调用debounce的对象,相当于_this.fn(args);
        // }, delay);
        timer = setTimeout(()=> {
            fn.apply(this, args); // 用apply指向调用debounce的对象,相当于this.fn(args);
        }, delay);
    };
}


// test
function testDebounce(e, content) {
    console.log(e, content);
}
var testDebounceFn = debounce(testDebounce, 1000); // 防抖函数
document.onmousemove = function (e) {
    testDebounceFn(e, 'debounce'); // 给防抖函数传参
}

什么是节流

即每隔一段时间,只执行一次函数。如游戏中的点击鼠标发射子弹,连续不断点按鼠标,并不会发射更多的子弹,而是按照一定的数量连续发射。

应用场景

1 滚动加载,加载更多或滚到底部监听
2 谷歌搜索框,搜索联想功能
3 高频点击提交,表单重复提交

函数防抖与节流的比较

都可以通过使用 setTimeout 实现。目的都是降低回调执行频率,节省计算资源。

节流代码

function throttle(fn, delay) {
    let timer;
    return function () {
        let _this = this;
        let args = arguments;
        if (timer) {
            return;
        }
        timer = setTimeout(function () {
            fn.apply(_this, args);
            timer = null; // 在delay后执行完fn之后清空timer,此时timer为假,throttle触发可以进入计时器
        }, delay)
    }
}


//test
function testThrottle(e, content) {
    console.log(e, content);
}
let testThrottleFn = throttle(testThrottle, 1000); // 节流函数
document.onmousemove = function (e) {
    testThrottleFn(e, 'throttle'); // 给节流函数传参
}
/**
 * 触发完事件 n 秒内不再触发事件,n秒后再执行
 * 只执行最后一次点击
 * @param event
 * @param time
 * @param flag 是否立即执行
 * @returns {Function}
 * @constructor
 */
export function debounce(event, time, flag) {
  const interval = time || 500
  let timer = null
  // 默认立即执行
  const f = flag || true
  return function(...args) {
    clearTimeout(timer)
    if (f && !timer) {
      event.apply(this, args)
    }
    timer = setTimeout(() => {
      event.apply(this, args)
    }, interval)
  }
}

/**
 * 只在单位时间内执行一次
 * 第一次事件不会触发,最后一次一定触发
 * @param event
 * @param time
 * @returns {Function}
 * @constructor
 */
export function throttle(event, time) {
  const interval = time || 500
  let timer = null
  return function(...args) {
    if (!timer) {
      timer = setTimeout(() => {
        timer = null
        event.apply(this, args)
      }, interval)
    }
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值