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

news2024/11/17 14:39:18

前言

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

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

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

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

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.coloradmin.cn/o/1891753.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言版,链表头插法与尾插法

最近又开始看数据结构与算法&#xff0c;看到这个头插法还真的是头插法&#xff0c;头都搞疼了&#xff0c;略微理解了一些。尾插法还好一些&#xff0c;比较好理解&#xff0c;但是如果深入理解还是可以理解。 头插法核心代码&#xff1a; head->next NULL; s->next h…

C++11新特性【下】{lambda表达式、可变模板参数、包装器}

一、lambda表达式 在C98中&#xff0c;如果想要对一个数据集合中的元素进行排序&#xff0c;可以使用std::sort方法。如果待排序元素为自定义类型&#xff0c;需要用户定义排序时的比较规则&#xff0c;随着C语法的发展&#xff0c;人们开始觉得上面的写法太复杂了&#xff0c…

Linux高并发服务器开发(十)反应堆模型和线程池模型

文章目录 1 epoll反应堆2 线程池流程代码 3 复杂版本线程池代码 1 epoll反应堆 文件描述符 监听事件 回调函数 进行封装 创建socket设置端口复用绑定监听创建epoll树将监听文件描述符lfd上epoll树&#xff0c;对应的事件节点包括&#xff1a;文件描述符&#xff0c;事件epoll…

ASP.NET Core Blazor 5:Blazor表单和数据

本章将描述 Blazor 为处理 HTML 表单提供的特性&#xff0c;包括对数据验证的支持。 1 准备工作 继续使用上一章项目。   创建 Blazor/Forms 文件夹并添加一个名为 EmptyLayout.razor 的 Razor 组件。本章使用这个组件作为主要的布局。 inherits LayoutComponentBase<div …

UnityUGUI之三 Text

富文本 常用语法&#xff1a; 1.加粗 <b> text </b> 2.斜体 <i> text </i> 3.尺寸 <size?> text </size> 4.颜色 <color#ff0000> text </color>

qt 滚动区域简单实验

1.概要 有些时候&#xff0c;想用一个有限的区域显示更多的内容&#xff0c;且内容不固定用滚动区域控件是一个不错的选择&#xff0c;我今天就用一个图片简单的实验一下。 2.代码&#xff08;关键代码&#xff09; #include "widget.h" #include "ui_widget…

antd+vue——实现table组件跨页多选,已选择数据禁止第二次重复选择

需求场景&#xff1a;点击【新增】按钮可以在分页弹窗中跨页多选选择数据后添加到页面中&#xff0c;再次点击【新增】&#xff0c;已经选择过的数据则置灰不让重复选择。 选择后&#xff0c;置灰 点击【确定】数据添加到页面中&#xff0c;可再次点击【新增】进行添加数据 …

JS基础与Chrome介绍

导言 在Web开发中后端负责程序架构和数据管理&#xff0c;前端负责页面展示和用户交互&#xff1b;在这种前后端分离的开发方式中&#xff0c;以接口为标准来进行联调整合&#xff0c;为了保证接口在调用时数据的安全性&#xff0c;也为了防止请求参数被篡改&#xff0c;大多数…

C语言常见概念

目录 1. C语言是什么&#xff1f; 2. C语言的历史 3 编译和链接 4. VS项目和源文件、头文件介绍​编辑 5.创建项目 6.main函数​编辑 7. printf和库函数 8. 关键字介绍 9. 字符和ASCII编码 10. 字符串和\0 1. C语言是什么&#xff1f; 人和计算机交流的语言工具&…

CVD-Risk-Prevent 个性化心血管健康推荐系统:基于医学指南的规则框架与 LLM 的结合

CVD-Risk-Prevent 个性化心血管健康推荐系统&#xff1a;基于医学指南的规则框架与 LLM 的结合 提出背景推荐算法的选择选择疑问健康指标管理心血管风险因素目标设定实现目标的计划推荐的多维性 算法关键点&#xff1a;如何将心血管健康指标转换为多维推荐&#xff1f;确定风险…

热备路由HSRP与VRRP

一、什么是HSRP HSRP&#xff08;Hot Standby Router Protocol&#xff09;是Cisco的专有协议&#xff0c;用于实现网络中路由器的冗余和故障转移。通过HSRP&#xff0c;可以将多台路由器组成一个“热备份组”&#xff0c;形成一个虚拟路由器。在这个组内&#xff0c;只有一个…

理解Netty的核心概念

一、理解Netty Netty是一个用于开发高性能网络应用的框架。为了更容易理解它&#xff0c;下面一些描述&#xff0c;不一定准确&#xff0c;但一定容易理解。 从Netty的Channel开始&#xff0c;把Netty所有的核心概念都串起来。 Channel 简单理解为一个连接。 有一个特殊的C…

Datadog Dash 2024 新功能解析

Datadog 2024 年的 Dash 刚刚落下帷幕&#xff0c;作为正在与 Datadog 开始竞争的观测云&#xff0c;我们认真仔细的分析了 Datadog 的每一个新功能&#xff0c;发现一些很有意思的事情&#xff0c;今天就给大家做一次全面的分析。&#xff08;所有 Datadog 的 Dash 的最新功能…

《UDS协议从入门到精通》系列——图解0x86:事件响应

《UDS协议从入门到精通》系列——图解0x86&#xff1a;事件响应 一、简介1.1 什么是事件响应&#xff1f;跟其他服务有何不同&#xff1f;1.2 到底如何理解事件响应机制&#xff1f;1.3 使用事件响应机制有哪些注意点&#xff1f; 二、数据包格式三、通信示例 Tip&#x1f4cc;…

VBA通过Range对象实现Excel的数据写入

前言 本节会介绍通过VBA中的Range对象&#xff0c;来实现Excel表格中的单元格写入、区域范围写入&#xff0c;当然也可以写入不同类型的数据&#xff0c;如数值、文本、公式&#xff0c;以及实现公式下拉自动填充的功能。 一、单元格输入数据 1.通过Value方法实现输入不同类型…

去中心化社会的崛起:探索区块链对社会结构的影响

随着区块链技术的发展和应用&#xff0c;我们正逐步迈向一个去中心化的社会结构。本文将深入探讨区块链技术如何影响社会结构&#xff0c;从经济、政治到文化等多个方面进行探索和分析&#xff0c;揭示其可能带来的革命性变革。 1. 区块链技术的基本原理回顾 1.1 分布式账本与…

从 ClickHouse 到 Apache Doris:快成物流的数智化货运应用实践

导读&#xff1a;随着快成物流的大宗商品产业链的不断发展&#xff0c;货运轨迹规划和实时数据分析的需求日益迫切&#xff0c;为了保障数据报表更新、用户画像圈选与物流轨迹实时更新等大数据核心系统性能&#xff0c;快成物流引入 Apache Doris 实时数仓升级了大数据算法平台…

vue2使用use注册自定义指令实现输入控制与快捷复制

使用场景 在一些form表单填写内容的时候&#xff0c;要限制输入的内容必须是数值、浮点型&#xff0c;本来el-input-number就可以实现&#xff0c;但是它本身带那个数值控制操作&#xff0c;等一系列感觉不舒服的地方。如果只是使用el-input该多好&#xff0c;只要监听一下输入…

docker安装ElasticSearchKibana

本文参考以下两篇文章 ✅ElasticSearch&Kibana 部署 云效 Thoughts 企业级知识库 (aliyun.com) docker安装ElasticSearch&Kibana - 飞书 安装elasticsearch 使用docker下载es&#xff1a; docker pull elasticsearch:8.13.0 挂载配置 创建挂在文件目录 mkdir…

AIGC在软件开发中的应用

目录 1. AIGC技术概述1.1 定义与背景1.2 发展历程 2. AIGC在软件开发中的应用2.1 代码生成2.2 错误检测与修复2.3 自动化测试 3. AIGC对开发者职业前景的影响3.1 助力与赋能开发者代码示例&#xff1a;自动化测试 3.2 技能需求转变与职业转型压力代码示例&#xff1a;AIGC辅助的…