面试高频题——解释一下节流

什么是节流

在计算机编程尤其是前端开发领域,"节流"(Throttling)是一种优化技术,用于控制函数的调用频率,以避免在短时间内因高频触发事件而导致的性能问题。具体来说,节流保证一个函数在特定的时间间隔内只执行一次,即使在这段时间内事件被触发多次。这种方式可以有效减少如滚动事件、窗口大小调整(resize)等连续且频繁触发的操作对性能的影响,从而提升用户体验和应用的响应速度。

节流的基本原理是使用定时器。当第一次事件触发时,会立即执行函数,并设置一个定时器,在指定的时间间隔之后才能再次触发该函数。如果在这段时间内又有新的事件触发,定时器会被重置,从而保证从最后一次触发事件开始,至少要等待预设的时间间隔后,函数才会被执行。这样,无论事件触发多么频繁,函数的实际执行频率都被限制住了。

节流的实现

html 复制代码
<div class="row">
    <div>
        没有节流的input <input type="text" id="inputa" />
    </div>
    <div>
        节流后的input <input type="text" id="inputc" />
    </div>
</div>
  • 非节流状态的JavaScript代码

每次在输入框输入内容,就会触发ajax函数

javascript 复制代码
const inputa = document.getElementById('inputa');

const ajax = (content) => {
    console.log(`ajax request ${content}`);
}
  • ajax(content):模拟一个耗时的网络请求操作,这里简单地输出到控制台。 可以看到右边的输出,只要我输入一次,就会执行一次,在大型项目中,我们要规避,要优化代码的性能
  • 节流状态的JavaScript代码
ini 复制代码
const inputa = document.getElementById('inputa');
const inputc = document.getElementById('inputc');

const ajax = (content) => {
    console.log(`ajax request ${content}`);
}

// 节流功能
const throttle = (func, delay) => {
    let last, deferTimer;

    return (args) => {
        let now = +new Date();
        if (last && now - last < delay) {
           clearTimeout(deferTimer)
                deferTimer =setTimeout(() => {
                   last = now
                   func(args)
               },delay)   
        } else {
            last = now;
            func(args);
        }
    }
}
  • throttle(func, delay):定义节流函数,接收一个待执行的函数func和延迟时间delay作为参数。 这里我们考虑到一个问题,用户在最后一次输入时,刚好是在一个delay时间之内,那不就不会输出最后输入的值

所以要在if条件中添加一个清除函数,让程序可以保留用户的最后一次输入,实现不遗漏的执行

ini 复制代码
const inputa = document.getElementById('inputa');
const inputc = document.getElementById('inputc');

const ajax = (content) => {
    console.log(`ajax request ${content}`);
}

// 节流功能
const throttle = (func, delay) => {
    let last, deferTimer;

    return (args) => {
        let now = +new Date();
        if (last && now - last < delay) {
           clearTimeout(deferTimer)
                deferTimer =setTimeout(() => {
                   last = now
                   func(args)
               },delay)   
        } else {
            last = now;
            func(args);
        }
    }
}
  • 闭包中的lastdeferTimerlast用于存储上一次执行的时间戳,deferTimer则用于管理定时器。

最后就是事件监听的绑定

ini 复制代码
inputa.addEventListener('keyup', (e) => {
    ajax(e.target.value);
});

let throttledFunc = throttle(ajax, 1000);

inputc.addEventListener('keyup', (e) => {
    let value = e.target.value;
    throttledFunc(value);
});
  • inputa上的keyup事件直接调用ajax函数,无任何节流处理。
  • inputc上的keyup事件则调用经过节流处理的函数throttledFunc,确保在1秒内最多只发送一次网络请求。

自此我们就完成了节流的实现

结语

防抖和节流是在面试中面试官提问频率最高的问题之二,从细节上去解释,可以让你在面试官的印象里比其他竞争者更加有优势。

相关推荐
祈祷苍天赐我java之术5 分钟前
Vue 整体框架全面解析
前端·javascript·vue.js
Python私教16 分钟前
Django全栈班v1.04 Python基础语法 20250912 上午
后端·python·django
华仔啊1 小时前
为什么 keySet() 是 HashMap 遍历的雷区?90% 的人踩过
java·后端
华仔啊1 小时前
前端登录token到底应该存在哪?LocalStorage、SessionStorage还是Cookie?一篇说透!
前端·javascript
9号达人1 小时前
Java 13 新特性详解与实践
java·后端·面试
用户49055816081251 小时前
keepalived原理之持有vip是什么意思
后端
想用offer打牌1 小时前
线程池踩坑之一:将其放在类的成员变量
后端·面试·代码规范
心月狐的流火号1 小时前
Redis 的高性能引擎 Reactor 详解与基于 Go 手写 Redis
redis·后端
橙序员小站1 小时前
搞定系统设计题:如何设计一个支付系统?
java·后端·面试
Java水解1 小时前
Spring Boot + ONNX Runtime模型部署
spring boot·后端