从搜索框的提示词中再探防抖和节流

前言

最近逛掘金时,看到了一篇文章。发现是我之前写过的一篇文章主题是防抖和节流的,看防抖时没感觉哪里不一样,但是当我看到节流时发现他的节流怎么这么繁琐(・∀・(・∀・(・∀・*)?

抱着疑惑的想法,我仔细拜读了这篇文章。嗯。。好家伙不得不说大佬就是大佬,考虑的确实真的很细。里面的一些思想真的值得学习。今天就分享一下学习心得。代码我会贴在文章末尾。

为什么我们需要节流和防抖

举个栗子,你每次使用某度的搜索框,你每写一个字都会给你展示出相应的提示栏,类似下面这样

image.png

本质是通过监听input框的输入来通过网络请求向后端拿取数据的。乍看一眼没啥问题,但是监听input框的输入是只要进行了键盘敲击(敲击一个字母都算)就会触发回调函数向后端接口进行网络请求,一个人可能没啥事。但是百度多少用户,同时敲击直接给后台干冒烟了( ˶ˆ ᗜ ˆ˵ ),防抖和节流就是为了避免这种事情的发生。

防抖

防抖(Debounce)是一种控制函数执行频率的策略。防抖的主要目的是确保在一系列连续的调用中,只有当最后一次调用后的指定时间间隔内没有新的调用发生,该函数才会被执行一次。
那我们如何实现防抖呢?

setTimeout的作用

防抖的核心在与连续的调用中只执行最后一次,这意味着除了最后一次的执行前面的函数的调用都必须取消,但是函数如果调用了的话,js引擎会立即执行。所以控制函数的调用我们必须借用setTimeout,setTimeout可以延缓函数的调用,这意味着我们可以在延缓的时间内进行判断,如果函数再次被调用了的话,就取消前面的那一次函数调用。直到最后一次函数被调用,这样我们就确保函数只被调用最后一次。

代码

     // fnc 代表着你要执行的函数,delay代表着你希望多长时间后用户不进行操作了然后执行函数
function Debounce(fn, delay) {
        // 记录定时器的
        let timer = null;
        return function () {
        // 如果存在timer就表示有函数正在等待执行,
        //取消前面函数的等待,重新进行当前函数的等待
            if (timer) { clearInterval(timer) }
            timer = setTimeout(() => {
            fn(键盘敲击的值); }, 
            delay);
        }
    }

防抖案例代码(查看效果需要查看console.log()打印的结果):
jcode

节流

节流(Throttling)也是一种控制函数执行频率的策略,用于限制某个函数的执行频率。它的核心目的是在特定的时间间隔内,无论函数被调用多少次,都确保该函数只也一定会执行一次。

这个是重头戏

看完了防抖的原理相信你对防抖有了一定的认知,其实节流也是通过定时器来实现。节流的重点是限制某个函数的执行频率,一段时间内只执行一次!实现方法就是使用定时器,来延缓执行,如果后面函数任然进行了调用,我们就不执行函数的调用,在定时器内的函数没有调用之前其他的函数调用我全部都取消。

如果定时器内的函数已经执行完成,那么下一次函数的调用又会重新进入定时器。


下面是我的代码

 // fnc 代表着你要执行的函数,delay代表着你希望执行函数的时间频率
function Throttle(fn, delay) {
        let timer = null;
        return function (url, keywords) {
        // 如果定时器以及存在,其他函数的调用不执行直接返回
            if (timer) return;
       // 不存在就进入定时器
            timer = setTimeout(() => {
                fn(键盘敲击的值);
                timer = null;
            }, delay);
        }
    }

ok,可能这样看下来你觉得没什么问题。实际确是有不足之处,回到之前的应用场景,我们监听的是键盘的敲击事件,相信大家还记得。

你敲击键盘,某度给你的提示词是你敲击完成之后对你进行提示。但是你再仔细看看我上面的这段代码。

 if (timer) return;

这里会出现什么我们不想要的结果呢?
举个栗子,就是当我只敲击2个字时,第一个字敲击的时候定义了一个定时器假设时间为1s,那么我在接下来的任何敲击触发的函数都无法接受。而此时定时器内的函数所接收的用户输入值确是我第一次敲击所产生的,那么像后端发送的请求也是第一次敲击产生的提示词,而并非最后一次。这样的情况并不是我们所期望看见的。

以下是大佬的做法,就可以避免最后一次敲击被遗漏。

// fnc 代表着你要执行的函数,delay代表着你希望执行函数的时间频率
const throttle = (func, delay) => {
        // last 上一次是啥时候执行的,timer依然是记录定时器
        let last, timer;
        return () => {
            // 当前时间,隐式转换为数字类型
            // 每次用户敲击我都记录当前时间为now
            let now = +new Date();
            // 如果last也就是上次函数执行的时间
            // 当前时间并不满足时间间隔那么我们就进入if语句
            if (last && now < delay + last) {
            // 如果最后一次敲击,取消定时器
                clearTimeout(timer);
            // 定义一个延迟函数的执行,用来满足用户的最后一次敲击被执行
                timer = setTimeout(() => {
                    last = now;
                    func([键盘敲击值]);
                }, delay);
            }
            //如果用户没有点击过或者,已经隔了delay时间没有点击就执行函数
            else {
            // 记录当前函数执行的时间
                last = now;
                func();
            }
        }
    }

节流详细代码(查看效果需要查看console.log()打印的结果):
jcode

结语

实话,我自己在学的时候一度也认为有点抽象。但是在明白了应用场景也就是提示词需要进行最后一次点击进行提示这个功能需求后。我明白了,写本篇文章也希望给和我一样在学习防抖和节流遇到困难的小伙伴一个思路与提示。
今天的文章就分享到这,喜欢的话就点个关注或者是赞吧。谢谢你啦- ̗̀(๑ᵔ⌔ᵔ๑)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/769281.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PyCharm 如何设置作者信息

1、点击pycharm右上角的齿轮&#xff0c;选择settings 2、选择editor 3、选择 Editor File and Code Templates 4、选择作者信息的文件类型&#xff0c;中间选择框选择Python Script 5、然后在右边的输入框中输入相关的信息 # -*- coding: utf-8 -*- """ Time …

kotlin接口,前端怎么调用?

文章目录 &#x1f389;欢迎来到Java学习路线专栏~探索Java中的静态变量与实例变量 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&#xff1a;IT陈寒的博客&#x1f388;该系列文章专栏&#xff1a;Java学习路线&#x1f4dc;其他专栏&#xff1a;Java学习路线 Jav…

构建大数据生态:Sqoop、Hadoop、IDEA和Maven的完整安装与数据预处理指南【实训Day03】

一、Sqoop安装 1 上传安装包并解压缩(在hadoop101上) # cd /opt/software 点击xftp上传sqoop的安装文件sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz # tar -zxvf sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz -C /opt/module/ # cd /opt/module/ # mv s…

vue3+vue-router+vite 实现动态路由

文章中出现的代码是演示版本&#xff0c;仅供参考&#xff0c;实际的业务需求会更加复杂 什么是动态路由 什么场景会用到动态路由 举一个最常见的例子&#xff0c;比如说我们要开发一个后台管理系统&#xff0c;一般来说后台管理系统都会分角色登录&#xff0c;这个时候也就涉…

基于Vue.js和SpringBoot的地方美食分享网站系统设计与实现

你好&#xff0c;我是计算机专业的学姐&#xff0c;专注于前端开发和系统设计。如果你对地方美食分享网站感兴趣或有相关需求&#xff0c;欢迎随时联系我。 开发语言 Java 数据库 MySQL 技术 Vue.js SpringBoot Java 工具 Eclipse, MySQL Workbench, Maven 系统展示…

【Spring Boot】关系映射开发(一):一对一映射

关系映射开发&#xff08;一&#xff09;&#xff1a;一对一映射 1.认识实体间关系映射1.1 映射方向1.2 ORM 映射类型 2.实现 “一对一” 映射2.1 编写实体2.1.1 新建 Student 实体2.1.2 新建 Card 实体 2.2 编写 Repository 层2.2.1 编写 Student 实体的 Repository2.2.2 编写…

AMEYA360代理:海凌科60G客流量统计雷达模块 4T4R出入口绊数计数

数字化时代&#xff0c;不管是大型商城还是各种连锁店&#xff0c;客流统计分析都可以帮助企业更加精准地了解顾客需求和消费行为。 海凌科推出一款专用于客流量统计的60G雷达模块&#xff0c;4T4R&#xff0c;可以实时进行固定范围内的人体运动轨迹检测&#xff0c;根据人体的…

0703_ARM7

练习&#xff1a; 封装exti&#xff0c;cic初始化函数 //EXTI初始化 void hal_key_exti_init(int id,int exticr,int mode){//获取偏移地址int address_offset (id%4)*8;//获取寄存器编号int re_ser (id/4)1;//printf("address_offset%d,re_ser%d\n",address_o…

学会python——用python编写一个电子时钟(python实例十七)

目录 1.认识Python 2.环境与工具 2.1 python环境 2.2 Visual Studio Code编译 3.电子时钟程序 3.1 代码构思 3.2代码实例 3.3运行结果 4.总结 1.认识Python Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的可读性…

软件模型分类及特点

在软件开发的世界里&#xff0c;我们经常会遇到业务模型、系统模型和软件模型这三个层次。这些模型各有特点&#xff0c;相互之间也有着紧密的联系。通过理解这三个层次之间的映射关系&#xff0c;我们能更好地理解和掌握软件开发的全过程 1. 业务模型 业务模型描述了组织的业…

搜维尔科技:Xsens实时动作捕捉,驱动人形机器人操作!

搜维尔科技&#xff1a;http://www.souvr.comhttp://www.souvr.com实时动作捕捉&#xff0c;驱动人形机器人操作&#xff01; 搜维尔科技&#xff1a;Xsens实时动作捕捉&#xff0c;驱动人形机器人操作&#xff01;

方向导数和梯度

方向导数和梯度 1 导数的回忆2 偏导数及其向量形式偏导数的几何意义偏导数的向量形式 3 方向导数向量形式几何意义方向导数和偏导的关系 4 梯度5 梯度下降算法 1 导数的回忆 导数的几何意义如图所示&#xff1a; 当 P 0 P_{0} P0​点不断接近 P P P时&#xff0c;导数如下定义…

vue 中使用element-ui实现锚点定位表单

效果图&#xff1a; 代码&#xff1a; html代码&#xff1a; <div class"content-left"><el-tabs :tab-position"left" tab-click"goAnchor"><el-tab-pane v-for"(item,index) in anchorNameList"v-anchor-scroll:ke…

LeetCode 60.排序排列(dfs暴力)

给出集合 [1,2,3,...,n]&#xff0c;其所有元素共有 n! 种排列。 按大小顺序列出所有排列情况&#xff0c;并一一标记&#xff0c;当 n 3 时, 所有排列如下&#xff1a; "123""132""213""231""312""321" 给定…

基于RSA的数字签名设计与实现

闲着没事把大三的实验发一下 这里用的技术和老师要求的略有不同但大体相同 1. RSA算法简介 公钥密码体制中,解密和加密密钥不同,解密和加密可分离,通信双方无须事先交换密钥就可建立起保密通信,较好地解决了传统密码体制在网络通信中出现的问题.另外,随着电子商务的发展,网络…

transformer模型学习路线_transformer训练用的模型

Transformer学习路线 完全不懂transformer&#xff0c;最近小白来入门一下&#xff0c;下面就是本菜鸟学习路线。Transformer和CNN是两个分支&#xff01;&#xff01;因此要分开学习 Transformer是一个Seq2seq模型&#xff0c;而Seq2seq模型用到了self-attention机制&#xf…

Python | Leetcode Python题解之第205题同构字符串

题目&#xff1a; 题解&#xff1a; class Solution:def isIsomorphic(self, s: str, t: str) -> bool:dicts Counter(s)dictt Counter(t) if list(dicts.values()) ! list(dictt.values()):return Falsefor i in range(len(s)):inds list(dicts.keys()).index(s…

【postgresql】 数据类型

数字类型 名字存储尺寸描述范围smallint2字节小范围整数-32768 ~32767integer4字节整数的典型选择-2147483648 ~ 2147483647bigint8字节大范围整数-9223372036854775808 ~ 9223372036854775807decimal可变用户指定精度&#xff0c;精确最高小数点前131072位&#xff0c;以及小…

python sklearn机械学习模型-回归

&#x1f308;所属专栏&#xff1a;【机械学习】✨作者主页&#xff1a; Mr.Zwq✔️个人简介&#xff1a;一个正在努力学技术的Python领域创作者&#xff0c;擅长爬虫&#xff0c;逆向&#xff0c;全栈方向&#xff0c;专注基础和实战分享&#xff0c;欢迎咨询&#xff01; 您…

使用SpringBoot整合Servlet

一、SpringBoot和Servlet的整合 1、用注解WebServlet配置Servlet映射 创建一个SpringBoot的web工程&#xff0c;在工程用创建一个Servlet 2、在SpringBoot的启动类上加注解ServletComponentScan 二、额外的方式 1、不使用WebServlet配置Servlet映射 创建一个SpringBoot工…