葵花宝典

vuePress-theme-reco 前端小菜-贺俊兰    2026
葵花宝典 葵花宝典

Choose mode

  • 关灯
  • 自动
  • 开灯
主页
分类
  • LeetCode
  • JavaScript
  • Node
  • 其他
  • VUE
标签
时间轴
author-avatar

前端小菜-贺俊兰

33

文章

7

标签

主页
分类
  • LeetCode
  • JavaScript
  • Node
  • 其他
  • VUE
标签
时间轴
  • javascript

    • JavaScript小技巧
    • javascript之基本数据类型
    • javascript计算精度丢失解决方案
    • 记录一次简单的防抖节流

记录一次简单的防抖节流

vuePress-theme-reco 前端小菜-贺俊兰    2026

记录一次简单的防抖节流

前端小菜-贺俊兰 2020-08-28 JavaScript

# 防抖

# 定义

防抖的原理是不管你在一段时间内如何不停的触发事件,只要设置了防抖,则只在触发n秒后才执行。如果我们在一个事件触发的n秒内又触发了相同的事件,那我们便以新的事件为标准,n秒之后再执行。

个人理解:函数防抖就是法师放技能的时候要读条,技能读条没完再按技能就会重新读条。

# 使用场景

  1. 搜索框搜索输入。只需用户最后一次输入完,再发送请求
  2. 手机号、邮箱验证输入检测
  3. 窗口大小Resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。

# 简单的代码实现

原理:将若干个函数调用合成为一次,并在给定时间过去之后仅被调用一次。

function debounce(fn, delay) {
  // 维护一个 timer,用来记录当前执行函数状态
  let timer = null;

  return function() {
    // 通过 ‘this’ 和 ‘arguments’ 获取函数的作用域和变量
    let context = this;
    let args = arguments;
    // 清理掉正在执行的函数,并重新执行
    clearTimeout(timer);
    timer = setTimeout(function() {
      fn.apply(context, args);
    }, delay);
  }
}
let flag = 0; // 记录当前函数调用次数
// 当用户滚动时被调用的函数
function foo() {
  flag++;
  console.log('函数调用次数:', flag);
}

// 在 debounce 中包装我们的函数,过 2 秒触发一次
document.body.addEventListener('scroll', debounce(foo, 2000));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 节流

# 定义

在指定间隔内任务只执行1次。规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。

个人理解:类似限时发放福利,每个人在规定时间内只能领取一次。

# 使用场景

  1. 滚动加载,加载更多或滚到底部监听
  2. 鼠标不断点击触发,mousedown(单位时间内只触发一次)
  3. 高频点击提交,表单重复提交

# 简单的代码实现

原理:节流函数不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数。 代码实现有两种,一种是时间戳,另一种是定时器

时间戳实现:

function throttle(func, delay){
  let prev = Date.now();
  return function(){
    const context = this;
    const args = arguments;
    const now = Date.now();
    if(now - prev >= delay){
      func.apply(context, args);
      prev = Date.now();
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12

当高频事件触发时,第一次应该会立即执行(给事件绑定函数与真正触发事件的间隔如果大于delay的话),而后再怎么频繁触发事件,也都是会每delay秒才执行一次。而当最后一次事件触发完毕后,事件也不会再被执行了。

定时器实现:当触发事件的时候,我们设置一个定时器,在触发事件的时候,如果定时器存在,就不执行;直到delay秒后,定时器执行执行函数,清空定时器,这样就可以设置下个定时器。

fucntion throttle(func, delay){
  let timer = null;

  return funtion(){
    let context = this;
    let args = arguments;
    if(!timer){
      timer = setTimeout(function(){    
        func.apply(context, args);
        timer = null;
      }, delay);
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

当第一次触发事件时,肯定不会立即执行函数,而是在delay秒后才执行。 之后连续不断触发事件,也会每delay秒执行一次。 当最后一次停止触发后,由于定时器的delay延迟,可能还会执行一次函数。

# 总结

  1. 函数防抖和函数节流都是防止某一时间段内频繁触发,但是这两兄弟之间的原理却不一样。
  2. 函数防抖是某一段时间内只执行一次,多次触发时间重新计算,而函数节流是间隔时间执行。
欢迎来到 葵花宝典
看板娘