首页 > 其他分享 >从搜索框的提示词中再探防抖和节流

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

时间:2024-07-05 09:57:38浏览次数:18  
标签:防抖 调用 节流 词中 探防抖 timer 敲击 执行 函数

前言

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

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

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

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

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

结语

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

标签:防抖,调用,节流,词中,探防抖,timer,敲击,执行,函数
From: https://blog.csdn.net/qq_62012466/article/details/140165494

相关文章

  • 防抖与节流机制
    防抖与节流:本质上是优化高频率执行代码的一种手段浏览器的resize、scroll、keypress、mousemove等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能为了优化体验,需要对这类事件进行调用次数的限制,对此我们就可以采用防抖(debounce)和节流(throttle......
  • 防抖和节流的概念理解
    防抖:在事件被触发的n秒后执行回调,如果在这n秒内又被触发,则重新计时。<script>vartimer=null,functionfangdou(fn,delay){ clearTimeOut(timer) timer=setTimeOut(fn,delay)}functioncheckout(input){ fangdou(function(){ show(input.value) },1000)}functionsh......
  • 面试官:字节流可以处理一切文件为什么还需要字符流呢?
    一、写在开头在计算机领域中百分之九十以上的程序拥有着和外部设备交互的功能,这就是我们常说的IO(Input/Output:输入/输出),所谓输入就是外部数据导入计算机内存中的过程,输出则是将内存或者说程序中的数据导入到外部存储中,如数据库、文件以及其他本地磁盘等。二、什么是IO流这种......
  • JavaSE中的IO(输入/输出)字节流字符流
    JavaSE中的IO(输入/输出)知识是一个广泛的领域,它涵盖了如何在Java程序中进行数据的读取和写入。以下是对JavaSE中IO知识的一个清晰归纳:一、基础知识流(Stream)的概念流是一组有顺序的、有起点和终点的字节集合,用于数据传输。Java的I/O流提供了读写数据的标准方法。Java的I/O......
  • 重学java 63.IO流 字节流 ④ 文件复制
    身处泥泞,看满山花开               ——24.6.4图片复制分析1.创建两个对象        FilelnputStream—>读取指定的文件        FileOutputStream—>将读到的字节写到指定的位置2.边读边写importjava.io.FileInputS......
  • JAVA IO流(File类,字节流,字符流)
    File类分隔符:a.路径名称分隔符:windows:linux:/b.路径分隔符:一个路径和其他路径之间的分隔符;1.概述:文件和目录(文件夹)路径名的抽象表示2.File的静态成员staticStringpathSeparator:与系统有关的路径分隔符,为了方便,它被表示为一个字符串。staticStrings......
  • JAVAEE之文件IO_数据流概念,字节流:InputStream、OutputStream,字符流:reader、writer,及实
    什么是数据流 顾名思义,I表示input,O表示output,也就是输入输出流,主要是在程序与文件之间,用于传输数据的通道。既然要传输数据,那么我们需要理解文件和程序之间哪种方向的传输是输入流,哪种传输作为输出流?我们可以举一个例子,如下图所示: IO流是JavaIO中的核心概念。流......
  • 防抖函数 debounce 和节流函数 throttle
    明天考蓝桥web,复习下debounce和throttledebounce防抖函数应用场景:即时响应式的输入框、按钮等(毕竟没人知道用户究竟会怎么用)前置知识:闭包:与很多主流编程语言不同,JavaScript在变量作用域上具有一些特殊表现。(摘自mdn)闭包是由函数以及声明该函数的词法环境组合而成的。该环......
  • 【DRF-06】rest-framework之节流
    1.自定义节流类,基于用户IP限制访问频率1.1:自定义节流类importtimeVISIT_RECORD={}classVisitThrottle(BaseThrottle):'''#(1)取出访问者ip#(2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走#(3)循......
  • Lua定义字节流
    在Lua中,字节流通常表示为一系列字节(8位的数值)。由于Lua的表(table)是灵活的数据结构,可以作为数组和哈希表使用,因此可以用表来表示字节流。每个表元素代表一个字节,元素的索引表示字节在流中的位置。以下是一些定义和操作字节流的基本示例:定义空字节流localbyteStream={}定义......