前端面试题 你还不会防抖节流嘛? 带你手撕防抖节流。

学会防抖节流,这一篇文章就够了

哈喽哈喽,我是你们的金樽清酒。昨天我在面试的时候呀,面试官说有啥要问他的嘛,我想了一想,问咱们公司的项目有啥要性能优化的嘛,比如防抖节流啥的?引诱面试官上钩。面试官说,啊那你就说一下什么是防抖节流吧。那到你秀肌肉的时候啦,小小的防抖节流拿下。

什么是防抖!!!

什么是防抖呢?就是用户频繁的点击,猛戳屏幕,那你要触发几次呢,那肯定只能触发一次嘛,只有等用户不再猛戳屏幕,不再抖动的时候再执行操作,不然会重复的执行一个操作,极大的浪费性能。作为一个程序员来说,永远都不能相信客户怎么操作你的程序。所以我们就要做好防抖这个程序。

小demo展示

js 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <button id="btn">点击</button>
</body>
<script>
    let btn = document.getElementById('btn')
    btn.addEventListener('click', handle)
    function handle() {
        console.log('提交了')
    }
</script>

</html>

可以看到当用户点击的时候,用户一直向后端发送接口请求。假设一下这么一个场景,当网络不佳的时候,用户会一直发接口请求然后后端就会收到很多的接口请求,实际上这是可以避免的,我们只需要一次发送接口请求就行了。那我们就需要一个节流的高阶函数。

js 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <button id="btn">点击</button>
</body>
<script>
    let btn = document.getElementById('btn')
    btn.addEventListener('click', debounce(handle, 1000))
    function handle(e) {
        console.log('提交了')
    }

    function debounce(fn, wait) {
        let timer = null
        return function (...args) {
            // 清除定时器
            clearTimeout(timer)
            timer = setTimeout(() => {
                fn.call(this, ...args)
            }, wait)
        }
    }
</script>

</html>

我们可以写一个debounce函数,里面return一个函数,因为addEventListene的第二个参数就是一个函数,里面写一个定时器,执行我们要执行的内容,然后给这个定时器一个名称,在外面清除定时器,由于闭包的存在,函数的调用栈里面有上一个定时器的内容,所以可以清除上一个定时器,这样就达到了防抖的效果,直到用户不在"手抖"后再执行这个函数。但是我们会改变了this的指向,所以要用.call将this指针再指向fn,也就是指向我们要执行的那个函数。这样一个防抖的效果就实现了。

什么是节流!!!

什么是节流,就是在一定的时间内只执行一次操作。就像游戏中的英雄有cd一样,不可能一直放技能。比如一个搜索框,不能用户才输入一个字母就,边输入就框框的发接口请求,这样也会导致后端突然收到大量的接口请求。所以我们要用节流来控制在某一段时间内该操作只执行一次。

那么,如何实现节流呢???

js 复制代码
 function throttle(fn, wait) {//节流的方法
        let pre = Date.now()
        return function (...args) {
            let cur = Date.now()
            if (cur - pre > wait)
                fn.call(this, ...args)
            pre = cur//保存执行时的时间作为记录
        }
    }

我们无非就是想让函数在符合一个时间的条件下执行,那么我们可以用时间戳来完成。在函数调用的时候用一个时间戳来表示当前的时间。在返回的函数里面再记录一个时间戳,由于闭包的存在,外层的时间戳会被记录下来,于是只要里面的时间戳与外面的时间戳的差满足那个条件,那么我们的操作就执行一次,同时将执行时的时间戳记录下来,寻找下一个符合条件的时间。同时不要忘记this指针的指向问题。

好啦,防抖节流的分享到这里啦。希望有帮助到大家。如果有想一起学习,刷题,向大厂进发的可以加我的微信wxid_hs2b5ajazj4422。

相关推荐
vipbic1 小时前
别再把“做个H5”挂嘴边了:这个词,官方压根就没有定义过
前端
AI人工智能+电脑小能手2 小时前
【大白话说Java面试题 第87题】【Mysql篇】第17题:分布式事务的实现原理?
java·数据库·分布式·mysql·面试
ZC跨境爬虫3 小时前
跟着 MDN 学CSS day_39:(Flexbox 弹性盒子核心机制)
前端·css·ui·html·tensorflow
小陈同学呦3 小时前
前端如何处理订单状态导航的数据竞态问题
前端·javascript
开发者每周简报3 小时前
网海三部曲·无名宗师传
javascript·人工智能
喵个咪4 小时前
GoWind Toolkit 前端代码生成|Vue3(ElementPlus/Vben)、React(AntDesign)全自动一键生成教程
前端·vue.js·react.js
Cosolar4 小时前
从零写一个 Attention Is All You Need
人工智能·面试·架构
摆烂大大王5 小时前
玩转 OpenClaw:用 TaskFlow + Heartbeat 打造自动化工作流
前端·人工智能·自动化
zhangxingchao5 小时前
AI 大模型核心六:量化、Workflow 与 Agent、多轮 RAG
前端·人工智能·后端
梦想的颜色5 小时前
TypeScript 完全指南(上):从零开始掌握类型系统
前端·typescript