5分钟读懂js函数防抖\节流

166 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。


前言

今天来谈一谈JS中的函数防抖和函数节流,浅浅的剖析一下其中的一些门道。在实际项目中也会遇到一些应用场景需要使用到防抖和节流,包括在面试中也算是高频出现了,今天就与大家一同来学习一下。

菜鸡.webp

函数防抖

概念

触发事件后不是立即执行回调,而是设定一段时间后再执行回调,若在回调触发之前再次触发事件,则重新计时。 简言之,避免一段时间内太过频繁的触发事件回调(如输入框的input事件),尽量减少用户触发事件回调的次数,减少性能损耗。

例子

这里使用vue的写法来模拟一个input框实现函数防抖。

<template>
    <el-input v-model="test" @input="debounce"/>
</template>
<script>
    export default {
        data() {
            return {
                test: undefined,
                timer: undefined
            }
        },
        methods: {
            debounce() {
                if(this.timer) { // 清除定时器
                    clearTimeout(this.timer)
                }
                timer = setTimeout(() => {
                    //  具体业务实现
                    console.log(this.test)
                },1000)
            }
        }
    }
</script>

思路就是用一个定时器来控制事件回调中具体业务的延迟触发,若在设定的时间内再次触发事件回调,则清除定时器,重新再设置定时器,这样就可以有效的减少业务触发的次数。

函数节流

概念

设定一段时间内只触发一次事件回调,也就是n毫秒内不管触发多少次事件,都只执行一次回调。

例子

同样的用vue的写法来模拟input框实现函数节流。

<template>
    <el-input v-model="test" @input="debounce"/>
</template>
<script>
    export default {
        data() {
            return {
                test: undefined,
                open: true
            }
        },
        methods: {
            throttle() {
                if(this.open) { 
                    setTimeout(() => {
                    //  具体业务实现
                    console.log(this.test)
                    this.open = true
                },1000)
                }
                this.open = false
            }
        }
    }
</script>

原理其实也蛮简单的,就是类似于设定一个开关来控制定时器的运转,在你设置的间隔之内限制住了开关,在特定时间内就只能触发一次,这是利用定时器方法来实现函数节流,其实还有一种方法是使用时间戳方案来实现函数节流的做法,也来举例一下。

<template>
    <el-input v-model="test" @input="debounce"/>
</template>
<script>
    export default {
        data() {
            return {
                test: undefined,
                open: true
            }
        },
        methods: {
            throttle() {
                let now = Date.now()
                if(now - this.open >= 1000){
                    console.log(this.test)
                    this.open = Date.now()
                }
            }
        }
    }
</script>

这样也能实现函数节流的效果,原理就是判定是否超过所设定的时间间隔,若超过,则执行业务操作,若未超过,那就直接跳出函数。具体选用哪种方法就看大家自己的喜好了。

浅谈应用场景

函数防抖:在很多系统触发用户搜索的时候可以使用,最好是能确保用户填写完毕之后再请求数据,使用防抖来减少请求。当然还有其它很多地方可以使用,目前写文的时候就暂时想到了这个,大家可以灵活变通按照实际项目情况来使用。

函数节流:监听滚动事件时,一个比较常见的应用场景,滚动下拉加载数据。还有监听一些拖拽操作的同时也可以应用,具体还是要按照实际需求使用来分析。

总结

上面的代码只是简单实现了函数防抖和节流的功能,想做的更好一些也可以封装成工具函数来使用,两种方法都是为了优化程序性能,提升用户体验,在合适的时候使用这两种优化方案才能达到对应的效果。例如有些要求就是要让用户实时得到反馈,这时候用上节流和防抖就显得不太合适了,在用户体验和性能优化的选择上,总是要做一些取舍的,切勿滥用,按照实际情况来决定是否选用才好。

最后感谢各位看官能看到这里~