手写防抖节流以及它们的区别

本文讲述了防抖和节流两种技术的区别,它们都用于处理高频率函数触发,但防抖在规定时间内只执行一次,而节流则在执行后一段时间内暂停。作者还提供了简单的HTML和Vue代码示例,以及闭包原理在防抖和节流中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目的

       其实对于刚刚接触防抖节流的人来说,这两者好像常常一起说,而不是单拎出来说,实际上,他们是有区别的,针对的特定场景也不同,希望我的浅薄认知可以帮助到你

        相同点:其实都是用于处理函数触发频次过高的问题

        不同点:

                1.防抖是说在规定时间内如果再度触发了这个事件,那么之前的待执行事件将会终止,转而重新计时,大白话就是---规定时间内只执行一次,如果再度触发就终止并且重新计时

                2.节流是说,当事件执行后,规定时间内如果再度触发此事件,将不会执行(不生效),大白话说就是---函数执行后,在将来的一段时间内无法执行。

        场景:节流---搜索联想功能

                   防抖---手机号等需要判断的输入框(用户输入完后再判断)

        难点:防抖节流它涉及到闭包和this指向的问题,我个人认为实现一个简单的防抖节流搞懂闭包就行了,所以这里只是实现一个简单的功能。

        闭包:就是函数嵌套函数,内部函数使用了外部函数的变量,此时我们的js垃圾回收机制,它无法判断这个变量是不是应该被回收,导致这个变量一直在内存中,大家好好想想,那这个变量是不是就永远留着了呢,是不是就可以用来当作判断条件了呢?

代码部分

html:防抖和节流的html部分我写在一起了

<template>
  <input type="text" placeholder="测试防抖" v-model="inputVal" @keydown="search">
  <input type="text" placeholder="测试节流" v-model="inputVal2" @keydown="searchTwo">
</template>

<script setup>
import { ref } from 'vue';
import { debounce } from '@utils/debounce.js'
import { throttle } from '@utils/throttle.js'

let inputVal = ref('')
let inputVal2 = ref('')

//input 防抖
const search = debounce(function(){
  console.log('发送了请求,防抖');
},1000)

//input 节流
const searchTwo = throttle(function(){
  console.log('发送了请求,节流');
},1000,{
  leading:false,
  trailing:true
})

</script>

<style scoped>
</style>

防抖实现:

         大家仔细看,这个debounce函数是不是函数嵌套函数,并且内部函数使用了外部函数的timer这个变量,所以这里构成了闭包!!!,这个timer就可以当作后续的判断条件了

        我知道,肯定会有人想,为啥let timer = null这句话只初始化一次呢其实我们在防抖函数中是return了一个函数,意味着此时在html中search触发的只是return后的东西,整个函数debounce其实就执行了一次。

//这是封装的一个防抖函数
//防抖,理解为游戏中的回程,即在为施法时间内,再度触发,会取消之前的施法,再重新读条
//细节 let timer = null 这句实际上在只会初始化一次,这里的作用则是驻留变量
export function debounce (fun,time = 1000) {
    let timer = null
    return function () {
        //如果之前的定时器存在,那就清除它
        if(timer){
            clearInterval(timer)
        }
        timer = setTimeout(()=>{
            fun();
        }, time);
    }
}

节流的实现:

        当把防抖理解了那节流就水到渠成了,所以这里我就不解释了,总体也还是构成闭包。

//节流,理解为游戏中的技能cd,执行一次后,需要等冷却时间到了后,才能触发
export function throttle(fun,time=1000) {
    let interval = false;//当前函数的状态(冷却或未冷却)
    return function () {
        if(interval) {
            console.log('冷却中,无法执行');
            return;
        }else {//未冷却,可以执行
            interval = true;
            fun()
            setTimeout(()=>{
                interval = false;
            },time)
        }
    }
}

结语:如果我的代码或者语句有什么问题请告知我,如果能给我说明一下就更好了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值