函数防抖与函数节流

函数防抖

定义

触发高频事件后 n 秒内函数只会执行一次,如果 n 秒内高频事件再次被触发,则重新计算时间;更直白一点就是:一个需要频繁触发的函数,在规定时间内,只让最后一次生效,前面的不生效。

实现思路

每次触发事件时设置一个延迟调用方法,并且取消之前的延时调用方法。

应用场景

  • 搜索框输入
  • 手机号、邮箱输入检测
  • 拖拽窗口大小resize. 只要窗口调整完成之后,计算窗口大小,防止重复渲染

以搜索框输入为例

// 定义防抖函数,参数fn为具体应用中要使用的函数
function debounce(fn,delay) {
     // 创建一个标记用来存放定时器的返回值
     let timeout = null; 
     return function () {
       // 每当用户输入的时候把前一个 setTimeout clear 掉
       clearTimeout(timeout); 
       // 然后又创建一个新的 setTimeout, 这样就能保证输入字符后的 interval 间隔内如果还有字符输入的话,就不会执行 fn 函数
       timeout = setTimeout(() => { 
         fn.apply(this, arguments);
       }, delay);
     };
   }
   // 定义具体应用中要使用的函数
   function sayHi() {
     console.log('防抖成功');
   }
​
   var inp = document.getElementById('inp');
   // 利用监听事件使用防抖函数
   inp.addEventListener('input', debounce(sayHi,500)); 

函数节流

定义

高频事件触发,但在 n 秒内只会执行一次,所以节流会稀释函数的执行频率。更直白一点就是:一个函数执行后,只有大于设定的执行周期,才会执行第二次。

实现思路

每次触发事件时都判断当前是否有等待执行的延时函数,如果有,则直接return。

应用场景

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

以滚动加载为例

//节流throttle代码:
function throttle(fn,delay) {
    // 通过闭包保存一个标记
    let timer = null; 
    return function () {
         // 在函数开头判断标记是否为true,不为true则return
        if (timer) return;
        // 将外部传入的函数的执行放在setTimeout中
        timer = setTimeout(() => { 
            // 最后在setTimeout执行完毕后再把标记设置为null(关键)表示可以执行下一次循环了。
            // 当定时器没有执行的时候标记永远是false,在开头被return掉
            fn.apply(this, arguments);
            timer = null;
        }, delay);
    };
}
// 定义具应用中使用的函数
function sayHi() {
    console.log("hello world");
}
// 利用监听事件,使用函数节流
window.addEventListener('scroll', throttle(sayHi,500));

异同比较

相同点

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

不同点

  • 函数防抖,在一段连续操作结束后,处理回调,利用clearTimeout 和 setTimeout实现。函数节流,在一段连续操作中,每一段时间只执行一次,频率较高的事件中使用来提高性能。
  • 函数防抖关注一定时间连续触发的事件只在最后执行一次,而函数节流侧重于一段时间内只执行一次。

原创文章,作者:ZERO,如若转载,请注明出处:https://www.edu24.cn/course/javascript/js-throttle-debounce.html

Like (0)
Donate 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
ZEROZERO
Previous 2020年7月15日
Next 2020年7月20日

相关推荐

  • JavaScript基础知识八问

    JavaScript是前端开发中非常重要的一门语言,浏览器是他主要运行的地方。JavaScript是一个非常有意思的语言,但是他有很多一些概念,大家经常都会忽略。比如说,原型,闭包…

    2020年12月30日
    890
  • 日常开发 26 个常见的 JavaScript 代码优化方案

    1、NULL、Undefined、”【空】检查 我们在创建新变量赋予一个存在的变量值的时候,并不希望赋予null或undefined,我们可以采用以下简洁的赋值方式。 …

    2021年2月22日
    1.2K
  • JavaScript 事件委托详解

    基本概念 事件委托,通俗地来讲,就是把一个元素响应事件(click、keydown……)的函数委托到另一个元素; 一般来讲,会把一个或者一组元素的事件委托到…

    2021年3月8日
    989
  • 深入理解JS内存机制

    JS的内存机制在很多前端开发者看来并不是那么重要,但是如果你想深入学习JS,并将它利用好,打造高质量高性能的前端应用,就必须要了解JS的内存机制。对于内存机制理解了以后,一些基本的…

    2019年7月14日
    1.6K
  • js数组去重(区分object、“NaN”、NaN)

    数组去重在前端面试中比较常见,今天来复习复习。 对这样一个数组进行去重,我尝试了几种方法,大多数不能对对象去重,或者不能区分true和”true”、NaN和…

    2021年2月23日
    1.2K
  • 回调函数散记

    今天被将要入职的公司的开发人员询问了一个项目中遇到的问题,关于函数内访问外部函数的情况。大致现象如下:js文件中有两个同级函数FnA和FnB,想在函数FnA中调用FnB。 一看就是…

    2019年8月16日
    1.4K
  • 创建JavaScript对象的六种方式

    第一种:Object 构造函数创建 这行代码创建了 Object 引用类型的一个新实例,然后把实例保存在变量 Person 中。 第二种:使用对象字面量表示法 对象字面量是对象定义…

    2020年6月24日
    1.2K
  • 如何判断一个对象为数组

    使用 instanceof 操作符 原理 instanceof 的内部机制是通过判断对象的原型链中是不是能找到类型的 prototype。 使用 instanceof 判断一个对象…

    2020年7月3日
    1.0K
  • 前端遍历树形数据,返回满足条件的树形数据

    在一次做手机端小程序项目中,有一个机构表单项,需要在页面展示是树形层级结构,但是后端开发人员返回的数据却是一维数组,而且还要在前端做过滤筛选功能。但是在使用的手机端组件库中,却没有…

    2022年11月8日
    338
  • 深入理解JS原型和继承

    在学习JS中的原型,原型链,继承这些知识之前,必须先了解并掌握基础知识:函数和对象的关系。 我们一直都知道,函数也是对象的一种,因为通过instanceof就可以判断出来。但是函数…

    2019年6月29日
    2.0K

发表回复

Please Login to Comment