前端防抖与节流

本文详细介绍了前端开发中防抖(debounce)和节流(throttle)的概念及其区别,通过实例展示了如何在Vue和JavaScript中实现这两种优化技术。防抖用于限制函数的执行次数,如在输入框search联想中避免频繁请求;节流则用于控制函数执行频率,如在窗口resize事件中确保只执行一次。文章提供了具体的代码示例,帮助开发者更好地理解和应用防抖与节流。
摘要由CSDN通过智能技术生成

前端工作中免不了会用到防抖和节流,但是之前总容易搞混防抖和节流的定义,所以今天就来梳理一下防抖和节流的区别,以及如何使用的,什么时候应该用防抖,什么时候应该用节流。

问题描述

什么是前端防抖和节流?它们的区别是什么?怎么使用的?

防抖

概念:触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。

思路:每次触发事件的时候,清除定时器,然后从新设置新的定时器。

应用场景

•输入框search搜索联想,用户在不断输入值时触发input事件,用防抖来节约请求资源。•window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次

基本vue使用

onDebounce() {
    // timer是该对象全局定义的,每次执行onDebounce函数,调用的相同的timer
    clearTimeout(this.timer); 
    this.timer = setTimeout(()=>{
        this.getAjax(); // 后台请求ajax信息
    }, 2000);
},

基本js代码

function debounce(fn) {
  let timeout = null; // 创建一个闭包,保存一个标记用来存放定时器的返回值
  return function () {
    clearTimeout(timeout); // 每当用户输入的时候把前一个 setTimeout clear 掉
    timeout = setTimeout(() => { // 然后又创建一个新的 setTimeout, 这样就能保证输入字符后的 interval 间隔内如果还有字符输入的话,就不会执行 fn 函数
      fn.call(this);
    }, 500);
  };
}
document.getElementById('inp').addEventListener('input', debounce(getAjax)); // 防抖

节流

概念:高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率。

简要思路:每此触发事件时判断是否定时器已满,满则重新定时,否则不做任何事。

具体思路1:设置一个触发标志flag=true,在事件里面判断:如果flag==true,进行一次定时任务,并将flag=false,在定时任务里面执行获取ajax的代码,并将flag=true;如果flag=false,直接return出去不做任何事情,直到定时器满。

具体思路2:不使用定时器,直接比较时间戳差值。

应用场景

•鼠标不断点击触发,click/mousedown(单位时间内只触发一次)•监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断

思路1-vue代码

onThrottle() {
    if(!this.throttleFlag) return;
        
    this.throttleFlag = false;
    this.timer = setTimeout(()=>{
        this.getAjax();
        this.throttleFlag = true;
    }, 2000);
}

思路1-js代码

function throttle(fn) {
  let canRun = true; // 通过闭包保存一个标记
  return function () {
    if (!canRun) return; // 在函数开头判断标记是否为true,不为true则return
    canRun = false; // 立即设置为false
    setTimeout(() => { // 将外部传入的函数的执行放在setTimeout中
      fn.apply(this, arguments);
      // 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。当定时器没有执行的时候标记永远是false,在开头被return掉
      canRun = true;
    }, 500);
  };
}
window.addEventListener('resize', throttle(getAjax));

思路2-vue代码

onThrottle() {
    let now = Date.now();
    if (now - this.lastTime > 5000) { // 5s
        this.getAjax();
        this.lastTime = now; // update时间
    }
}

思路2-js代码

 function throttle (fn) {
    let lastTime = 0;  // 上次触发的时间
    return function () {
        let now = Date.now();
        if (now - lastTime > 5000) {
           fn.call(this);
           lastTime = now; // update时间
        }
    }
 }

参考链接

•7分钟理解JS的节流、防抖及使用场景[1]•Daily-Interview-Question[2]

引用链接

[1] 7分钟理解JS的节流、防抖及使用场景: https://juejin.im/post/5b8de829f265da43623c4261
[2] Daily-Interview-Question: https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/5

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值