你有没有过这种情况?在搜索框里快速打字找资料,结果每敲一个字母页面就抖一下加载,卡得鼠标都动不了;或者抢秒杀的时候太急,连着点了五六下提交,结果订单生成了好几个 —— 其实这都是没做 JS 防抖节流闹的!这俩玩意儿看着像专业术语,其实说白了就是给频繁触发的事件 “踩刹车”,今天咱们掰开揉碎了说,保证你看完就能用。

先唠防抖(Debounce),这玩意儿的核心逻辑特好记:“等你彻底停下来再说”。举个例子,你设置 1000 毫秒的延迟,只要用户在这 1 秒内又触发了事件(比如继续打字),就把之前的计时清空,重新开始算 1 秒。只有当用户真的停了 1 秒没动作,代码才会真正执行。

小索奇之前做电商项目就栽过这跟头。当时做商品搜索功能,没加防抖,用户输 “无线耳机” 五个字,后台直接接了五次请求,服务器日志刷得比瀑布还快。后来加了防抖,延迟设 800 毫秒,不管用户打得多快,只在停笔的瞬间发一次请求,服务器压力一下就降下来了,页面也不卡了。

再看节流(Throttle),这和防抖是两码事,它更像 “按点发车”。比如你设置 200 毫秒的间隔,不管用户在这 200 毫秒内触发多少次事件,它都只执行一次,等下一个 200 毫秒到了才允许再执行。

最典型的就是页面滚动加载。你想想看,要是没节流,用户往下滑一下,滚动事件能触发几十次,后台疯狂发请求要数据,页面直接白屏给你看。小索奇之前做资讯 APP 的列表页,一开始没处理,测试小哥滑了三下就喊 “崩了”,后来加了 200 毫秒节流,不管怎么滑,每 200 毫秒最多发一次请求,稳得一批。

光说不练假把式,直接上代码!先看防抖的实现,原生 JS 就能写,特简单:

function debounce (fn, delay) {

let timer = null;

return function (...args) {

// 每次触发都清空之前的定时器

if (timer) clearTimeout (timer);

// 重新设置定时器

timer = setTimeout (() => {

fn.apply (this, args);

// 执行完清空定时器

timer = null;

}, delay);

};

}

你瞅这逻辑,核心就是用 setTimeout 和 clearTimeout 配合。比如给搜索框加防抖,直接这么用:

const searchInput = document.getElementById ('search');

// 定义搜索函数

function handleSearch (value) {

console.log (' 搜索内容:', value);

// 这里写请求后台的逻辑

}

// 给输入框加防抖处理

searchInput.addEventListener ('input', debounce ((e) => {

handleSearch (e.target.value);

}, 800));

是不是特直观?接下来是节流,常用的有两种写法,先看时间戳版:

function throttleByTime (fn, delay) {

let lastTime = 0;

return function (...args) {

// 获取当前时间

const now = Date.now ();

// 对比当前时间和上次执行时间的差

if (now - lastTime >= delay) {

fn.apply (this, args);

// 更新上次执行时间

lastTime = now;

}

};

}

这种写法的特点是 “先执行,再等间隔”,比如第一次触发事件会马上执行,之后每隔 delay 毫秒执行一次。适合滚动加载这种需要即时响应的场景。

还有个定时器版,逻辑是 “先等间隔,再执行”:

function throttleByTimer(fn, delay) {

let timer = null;

return function(...args) {

if (!timer) {

timer = setTimeout(() => {

fn.apply(this, args);

timer = null;

}, delay);

}

};

}

这种第一次触发不会马上执行,要等 delay 毫秒后才动,适合按钮防重复点击,比如秒杀按钮,防止用户 1 秒内点十下生成十个订单。

说到这儿肯定有人问:“那我到底该用防抖还是节流啊?” 小索奇总结了个简单标准:要是事件是 “连续触发,但只需要最后一次结果”,比如搜索输入、窗口调整大小(resize)、文本框实时校验,就用防抖;要是事件是 “连续触发,需要按节奏执行”,比如滚动加载、鼠标移动绘图、按钮防重复点击,就用节流。

对了,还有个坑得提醒你!用防抖的时候别把延迟设太长,比如设 5 秒,用户等得花儿都谢了,早换别家网站了;节流的间隔也别太短,设 50 毫秒和没设差不多,太长又影响体验,一般 100-300 毫秒是黄金区间,亲测有效!

你之前做项目的时候踩过防抖节流的坑吗?或者有更炫酷的实现方式?欢迎在评论区聊聊!

我是【即兴小索奇】,点击关注,后台回复 领取,获取更多相关资源

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐