热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

关于前端:深入理解JavaScript防抖与节流

先不说概念,按本人的了解,在单反里,有防抖机制。因为人在拿着单反的时候会手抖(单反重),按下快门的霎时,照片会糊,所以有防抖机制,以避免老手把照片拍糊

防抖和节流都是闭包的利用,先了解闭包,再了解防抖和节流

防抖(debounce)

先不说概念,按本人的了解,在单反里,有防抖机制。因为人在拿着单反的时候会手抖(单反重),按下快门的霎时,照片会糊,所以有防抖机制,以避免老手把照片拍糊

单反中的防抖是避免抖动,让人拍出清晰的照片,Javascript 中的防抖是为了什么?

同理,它的作用也是避免抖动。试想当你频繁触发一个事件时,就会引起不必要的性能损失,那么让该事件在进行触发后再触发,以此缩小局部性能

防抖的定义

防抖就是要提早执行,你始终操作触发事件始终不执行,当你进行操作期待多少秒后才执行

也就是说不论事件触发频率有多高,肯定在事件触发 n 秒后执行。如果在事件触发的 n 秒又触发了这个事件,那就以新事件的事件为准,n 秒后才执行。总之,要等你触发完事件 n 秒内不再触发事件,它才执行

手写防抖

依据定义,咱们晓得要在工夫 n 秒后执行,那么咱们就用定时器来实现

function debounce(event, wait) {
  let timer = null;
  return function (...args) {
    clearTimeout(timer); // 革除setTimeout,使其回调函数不执行
    timer = setTimeout(() => {
      event.apply(this, args);
    }, wait);
  };
}

代码很简略,即当还在触发事件时,就革除 timer,使其在 n 秒后执行,但此写法首次不会立刻执行,为其健壮性,需加上判断是否第一次执行的第三个参数 flag,判断其是否立刻执行

function debounce(event, wait, flag) {
  let timer = null;
  return function (...args) {
    clearTimeout(timer);
    if (!timer && flag) {
      event.apply(this, args);
    } else {
      timer = setTimeout(() => {
        event.apply(this, args);
      }, wait);
    }
  };
}

防抖场景

窗口大小变动,调整款式

window.addEventListener('resize', debounce(handleResize, 200));

搜寻框,输出后 1000 毫秒搜寻

debounce(fetchSelectData, 300);

表单验证,输出 1000 毫秒后验证

debounce(validator, 1000);

防抖帝王库

两大工具库都有防抖源码,可供参考

lodash-debounce

underscore-debounce

节流(throttle)

顾名思义,一节一节的流,就好似管制水阀,在事件一直触发的过程中,固定工夫内执行一次事件

手写节流

因为是固定工夫内执行一次工夫,所以咱们有两种实现办法,一用工夫戳,二用定时器

工夫戳

function throttle(event, wait) {
  let pre = 0;
  return function (...args) {
    if (new Date() - pre > wait) {
      // 当 n 秒内不反复执行
      pre = new Date();
      event.apply(this, args);
    }
  };
}

应用工夫戳尽管能实现节流,然而最初一次事件不会执行

定时器

function throttle(event, wait) {
  let timer = null;
  return function (...args) {
    if (!timer) {
      timer = setTimeout(() => {
        timer = null;
        event.apply(this, args);
      }, wait);
    }
  };
}

应用定时器实现节流,尽管最初一次能触发,然而第一次不会触发

工夫戳 + 定时器

为解决第一次和最初一次都能够触发,把两者联合起来

function throttle(event, wait) {
  let pre = 0,
    timer = null;
  return function (...args) {
    if (new Date() - pre > wait) {
      clearTimeout(timer);
      timer = null;
      pre = new Date();
      event.apply(this, args);
    } else {
      timer = setTimeout(() => {
        event.apply(this, args);
      }, wait);
    }
  };
}

节流场景

scroll 滚动

window.addEventListener('scroll', throttle(handleScroll, 200));

input 动静搜寻

throttle(fetchInput, 300);

节流帝王库

lodash-throttle

underscore-throttle

总结

防抖:只执行最初一次。事件继续触发,但只有等事件进行触发后 n 秒后才执行函数

节流:管制执行频率。继续触发,每 n 秒执行一次函数

比照图:

线上 demo(司徒正美的 demo):防抖节流

参考资料

  • awesome-coding-js
  • 防抖节流场景及利用
  • 函数防抖与函数节流

系列文章

  • 深刻了解Javascript——开篇
  • 深刻了解Javascript——Javascript 是什么
  • 深刻了解Javascript——Javascript 由什么组成
  • 深刻了解Javascript——所有皆对象
  • 深刻了解Javascript——Object(对象)
  • 深刻了解Javascript——new 做了什么
  • 深刻了解Javascript——Object.create
  • 深刻了解Javascript——拷贝的机密
  • 深刻了解Javascript——原型
  • 深刻了解Javascript——继承
  • 深刻了解Javascript——Javascript 中的始皇
  • 深刻了解Javascript——instanceof——找祖籍
  • 深刻了解Javascript——Function
  • 深刻了解Javascript——作用域
  • 深刻了解Javascript——this关键字
  • 深刻了解Javascript——call、apply、bind三大将
  • 深刻了解Javascript——立刻执行函数(IIFE)
  • 深刻了解Javascript——词法环境
  • 深刻了解Javascript——执行上下文与调用栈
  • 深刻了解Javascript——作用域 VS 执行上下文
  • 深刻了解Javascript——闭包

推荐阅读
  • 本文详细介绍了使用 Python 进行 MySQL 和 Redis 数据库操作的实战技巧。首先,针对 MySQL 数据库,通过 `pymysql` 模块展示了如何连接和操作数据库,包括建立连接、执行查询和更新等常见操作。接着,文章深入探讨了 Redis 的基本命令和高级功能,如键值存储、列表操作和事务处理。此外,还提供了多个实际案例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • 本指南介绍了如何在ASP.NET Web应用程序中利用C#和JavaScript实现基于指纹识别的登录系统。通过集成指纹识别技术,用户无需输入传统的登录ID即可完成身份验证,从而提升用户体验和安全性。我们将详细探讨如何配置和部署这一功能,确保系统的稳定性和可靠性。 ... [详细]
  • 本文总结了JavaScript的核心知识点和实用技巧,涵盖了变量声明、DOM操作、事件处理等重要方面。例如,通过`event.srcElement`获取触发事件的元素,并使用`alert`显示其HTML结构;利用`innerText`和`innerHTML`属性分别设置和获取文本内容及HTML内容。此外,还介绍了如何在表单中动态生成和操作``元素,以便更好地处理用户输入。这些技巧对于提升前端开发效率和代码质量具有重要意义。 ... [详细]
  • JavaScript XML操作实用工具类:XmlUtilsJS技巧与应用 ... [详细]
  • 2.2 组件间父子通信机制详解
    2.2 组件间父子通信机制详解 ... [详细]
  • 在《Linux高性能服务器编程》一书中,第3.2节深入探讨了TCP报头的结构与功能。TCP报头是每个TCP数据段中不可或缺的部分,它不仅包含了源端口和目的端口的信息,还负责管理TCP连接的状态和控制。本节内容详尽地解析了TCP报头的各项字段及其作用,为读者提供了深入理解TCP协议的基础。 ... [详细]
  • C++ 异步编程中获取线程执行结果的方法与技巧及其在前端开发中的应用探讨
    本文探讨了C++异步编程中获取线程执行结果的方法与技巧,并深入分析了这些技术在前端开发中的应用。通过对比不同的异步编程模型,本文详细介绍了如何高效地处理多线程任务,确保程序的稳定性和性能。同时,文章还结合实际案例,展示了这些方法在前端异步编程中的具体实现和优化策略。 ... [详细]
  • Python 程序转换为 EXE 文件:详细解析 .py 脚本打包成独立可执行文件的方法与技巧
    在开发了几个简单的爬虫 Python 程序后,我决定将其封装成独立的可执行文件以便于分发和使用。为了实现这一目标,首先需要解决的是如何将 Python 脚本转换为 EXE 文件。在这个过程中,我选择了 Qt 作为 GUI 框架,因为之前对此并不熟悉,希望通过这个项目进一步学习和掌握 Qt 的基本用法。本文将详细介绍从 .py 脚本到 EXE 文件的整个过程,包括所需工具、具体步骤以及常见问题的解决方案。 ... [详细]
  • 提升Android开发效率:Clean Code的最佳实践与应用
    在Android开发中,提高代码质量和开发效率是至关重要的。本文介绍了如何通过Clean Code的最佳实践来优化Android应用的开发流程。以SQLite数据库操作为例,详细探讨了如何编写高效、可维护的SQL查询语句,并将其结果封装为Java对象。通过遵循这些最佳实践,开发者可以显著提升代码的可读性和可维护性,从而加快开发速度并减少错误。 ... [详细]
  • SQLite数据库CRUD操作实例分析与应用
    本文通过分析和实例演示了SQLite数据库中的CRUD(创建、读取、更新和删除)操作,详细介绍了如何在Java环境中使用Person实体类进行数据库操作。文章首先阐述了SQLite数据库的基本概念及其在移动应用开发中的重要性,然后通过具体的代码示例,逐步展示了如何实现对Person实体类的增删改查功能。此外,还讨论了常见错误及其解决方法,为开发者提供了实用的参考和指导。 ... [详细]
  • 本文详细探讨了Zebra路由软件中的线程机制及其实际应用。通过对Zebra线程模型的深入分析,揭示了其在高效处理网络路由任务中的关键作用。文章还介绍了线程同步与通信机制,以及如何通过优化线程管理提升系统性能。此外,结合具体应用场景,展示了Zebra线程机制在复杂网络环境下的优势和灵活性。 ... [详细]
  • 技术分享:深入解析GestureDetector手势识别机制
    技术分享:深入解析GestureDetector手势识别机制 ... [详细]
  • 地图集成方法与应用 ... [详细]
  • 在《Cocos2d-x学习笔记:基础概念解析与内存管理机制深入探讨》中,详细介绍了Cocos2d-x的基础概念,并深入分析了其内存管理机制。特别是针对Boost库引入的智能指针管理方法进行了详细的讲解,例如在处理鱼的运动过程中,可以通过编写自定义函数来动态计算角度变化,利用CallFunc回调机制实现高效的游戏逻辑控制。此外,文章还探讨了如何通过智能指针优化资源管理和避免内存泄漏,为开发者提供了实用的编程技巧和最佳实践。 ... [详细]
  • 本文深入解析了 jQuery 中用于扩展功能的三个关键方法:`$.extend()`、`$.fn` 和 `$.fn.extend()`。其中,`$.extend()` 用于扩展 jQuery 对象本身,而 `$.fn.extend()` 则用于扩展 jQuery 的原型对象,使自定义方法能够作为 jQuery 实例的方法使用。通过这些方法,开发者可以轻松地创建和集成自定义插件,增强 jQuery 的功能。文章详细介绍了每个方法的用法、参数及实际应用场景,帮助读者更好地理解和运用这些强大的工具。 ... [详细]
author-avatar
纯情利宾立2502857907
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有