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

什么是节流

在计算机编程尤其是前端开发领域,"节流"(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秒内最多只发送一次网络请求。

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

结语

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

相关推荐
海绵波波10714 分钟前
flask后端开发(1):第一个Flask项目
后端·python·flask
王小王和他的小伙伴19 分钟前
解决 vue3 中 echarts图表在el-dialog中显示问题
javascript·vue.js·echarts
学前端的小朱23 分钟前
处理字体图标、js、html及其他资源
开发语言·javascript·webpack·html·打包工具
outstanding木槿29 分钟前
react+antd的Table组件编辑单元格
前端·javascript·react.js·前端框架
小k_不小1 小时前
C++面试八股文:指针与引用的区别
c++·面试
好名字08211 小时前
前端取Content-Disposition中的filename字段与解码(vue)
前端·javascript·vue.js·前端框架
摇光931 小时前
js高阶-async与事件循环
开发语言·javascript·事件循环·宏任务·微任务
胡西风_foxww2 小时前
【ES6复习笔记】Class类(15)
javascript·笔记·es6·继承··class·静态成员
布兰妮甜2 小时前
使用 WebRTC 进行实时通信
javascript·webrtc·实时通信
艾斯特_2 小时前
JavaScript甘特图 dhtmlx-gantt
前端·javascript·甘特图