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

什么是节流

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

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

结语

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

相关推荐
Cherry的跨界思维1 分钟前
5、Python长图拼接终极指南:Pillow/OpenCV/ImageMagick三方案
javascript·python·opencv·webpack·django·pillow·pygame
by__csdn3 分钟前
第一章 (ASP.NET Core入门)第三节( 认识.NET Standard)
后端·c#·asp.net·.net·.netcore·f#·vb.net
向阳是我7 分钟前
v0.app的next.js项目自动部署到宝塔服务器教程
服务器·开发语言·javascript·github·ai编程
数据小馒头7 分钟前
生成测试数据(一):分钟级构建百万级数据,测试数据库性能
后端
重铸码农荣光9 分钟前
深入理解 JavaScript 继承:从原型链到 call/apply 的灵活运用
前端·javascript·面试
helloworld工程师11 分钟前
Dubbo应用开发之基于Dubbo协议的springboot规范性开发
spring boot·后端·dubbo
前端老宋Running13 分钟前
告别“祖传”defineProperty!Vue 3 靠 Proxy 练就了什么“神功”?
前端·vue.js·面试
码途进化论14 分钟前
前端Docker多平台构建自动化实践
前端·javascript·后端
悟空码字15 分钟前
SpringBoot 整合 RabbitMQ:和这只“兔子”交朋友
java·后端·rabbitmq
进击的野人16 分钟前
Vue中key的作用与Diff算法原理深度解析
前端·vue.js·面试