一、是什么

本质上是优化高频率执行代码的一种手段

如:浏览器的 resizescrollkeypressmousemove 等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能

为了优化体验,需要对这类事件进行调用次数的限制,对此我们就可以采用throttle(节流)和debounce(防抖)的方式来减少调用频率

定义

  • 节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次执行

  • 防抖: n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时

一个经典的比喻:

想象每天上班大厦底下的电梯。把电梯完成一次运送,类比为一次函数的执行和响应

假设电梯有两种运行策略 debouncethrottle,超时设定为15秒,不考虑容量限制

电梯第一个人进来后,15秒后准时运送一次,这是节流

电梯第一个人进来后,等待15秒。如果过程中又有人进来,15秒等待重新计时,直到15秒后开始运送,这是防抖

代码实现

节流

完成节流可以使用时间戳与定时器的写法

使用时间戳写法,事件会立即执行,停止触发后没有办法再次执行

function throttled1(fn, delay = 500) {let oldtime = Date.now()return function (...args) {let newtime = Date.now()if (newtime - oldtime >= delay) {fn.apply(null, args)oldtime = Date.now()}}
}

使用定时器写法,delay毫秒后第一次执行,第二次事件停止触发后依然会再一次执行

function throttled2(fn, delay = 500) {let timer = nullreturn function (...args) {if (!timer) {timer = setTimeout(() => {fn.apply(this, args)timer = null}, delay);}}
}

可以将时间戳写法的特性与定时器写法的特性相结合,实现一个更加精确的节流。实现如下

function throttled(fn, delay) {let timer = nulllet starttime = Date.now()return function () {let curTime = Date.now() // 当前时间let remaining = delay - (curTime - starttime)  // 从上一次到现在,还剩下多少多余时间let context = thislet args = argumentsclearTimeout(timer)if (remaining <= 0) {fn.apply(context, args)starttime = Date.now()} else {timer = setTimeout(fn, remaining);}}
}

防抖

简单版本的实现

function debounce(func, wait) {let timeout;return function () {let context = this; // 保存this指向let args = arguments; // 拿到event对象clearTimeout(timeout)timeout = setTimeout(function(){func.apply(context, args)}, wait);}
}

防抖如果需要立即执行,可加入第三个参数用于判断,实现如下:

function debounce(func, wait, immediate) {let timeout;return function () {let context = this;let args = arguments;if (timeout) clearTimeout(timeout); // timeout 不为nullif (immediate) {let callNow = !timeout; // 第一次会立即执行,以后只有事件执行后才会再次触发timeout = setTimeout(function () {timeout = null;}, wait)if (callNow) {func.apply(context, args)}}else {timeout = setTimeout(function () {func.apply(context, args)}, wait);}}
}

二、区别

相同点:

  • 都可以通过使用 setTimeout 实现

  • 目的都是,降低回调执行频率。节省计算资源

不同点:

  • 函数防抖,在一段连续操作结束后,处理回调,利用clearTimeoutsetTimeout实现。函数节流,在一段连续操作中,每一段时间只执行一次,频率较高的事件中使用来提高性能

  • 函数防抖关注一定时间连续触发的事件,只在最后执行一次,而函数节流一段时间内只执行一次

例如,都设置时间频率为500ms,在2秒时间内,频繁触发函数,节流,每隔 500ms 就执行一次。防抖,则不管调动多少次方法,在2s后,只会执行一次

如下图所示:

三、应用场景

防抖在连续的事件,只需触发一次回调的场景有:

  • 搜索框搜索输入。只需用户最后一次输入完,再发送请求

  • 手机号、邮箱验证输入检测

  • 窗口大小resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。

节流在间隔一段时间执行一次回调的场景有:

  • 滚动加载,加载更多或滚到底部监听

  • 搜索框,搜索联想功能

--The End--

系列正在更新:28/33

点击下方卡片解锁更多

创作不易,星标、点赞、在看 三连支持

面试官:说说函数节流和防抖?有什么区别?如何实现?相关推荐

  1. js 函数节流和防抖

    js 函数节流和防抖 throttle 节流 事件触发到结束后只执行一次. 应用场景 触发mousemove事件的时候, 如鼠标移动. 触发keyup事件的情况, 如搜索. 触发scroll事件的时候 ...

  2. 当面试官让你手写防抖、节流时,是在考察什么

    防抖.节流,都是用于节省函数调用次数的方案,达到优化程序.提升性能甚至是避免bug的目的.作为一个经典的主题,也是面试常考项,部分面试官会让你手写,这时, 他是在考察什么?你能轻易地写出比较好的防抖. ...

  3. 函数节流与防抖的实现

    函数节流与函数防抖 最近由于处于互联网大厂的秋招季节,因此这些天都在看前端性能优化和算法方面的知识.在性能优化方面,看了网上的一些文章,同时看完了<高性能网站建设指南>和<高性能Ja ...

  4. javascript函数节流、防抖及使用场景

    什么是函数节流 函数节流就是指定时间间隔内只执行一次任务,减少消耗,节省开支.比如水电站是用大坝来控制水的流量,达到细水长流,持续发电的作用.还比如早上客流高峰,地铁站会限制人流,运完一批人再放另一批 ...

  5. swf缓存文件在哪里_面试官:mybatis一级缓存二级缓存的区别都不知道,知道门在哪吧...

    面试官:虫虫你简历上写了了解mybatis缓存,那你能说说一级缓存和二级缓存的区别吗? 虫虫:我只知道这是用来缓存sql查询的数据 面试官:没了? 虫虫:没了 面试官:公司门知道在哪里吧 自己走还是我 ...

  6. php面试get和post的区别,UC头条:程序员: 面试官又问我post和get的区别了

    学院派?码农:PHP 我看到很多从事前端工作的头条作者们,在他们发表一段视频代码后,被很多人说"前端算程序员吗?"我就想说,你玻璃心吗? 每一个程序员应该都听说过程序员鄙视链,做c ...

  7. 面试官:说一下Redis和MongoDB的区别?

    项目中用的是MongoDB,但是为什么用其实当时选型的时候也没有太多考虑,只是认为数据量比较大,所以采用MongoDB. 最近又想起为什么用MongoDB,就查阅一下,汇总汇总: 之前也用过redis ...

  8. 面试官:super()和super(props)有什么区别?

    一.ES6类 在ES6中,通过extends关键字实现类的继承,方式如下: class sup {constructor(name) {this.name = name}printName() {co ...

  9. ege限制鼠标移动的函数_浅谈函数节流和函数防抖

    什么是函数节流和函数防抖?下面本篇文章就来给大家浅谈一下函数节流和函数防抖.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. 前言 事件的触发权很多时候都属于用户,有些情况下会产生问题 ...

最新文章

  1. HihoCoder 1671 DFS
  2. vue学习笔记(WebStorm安装)
  3. 检测电脑硬件的软件_为电脑DIY爱好者推荐一款非常实用的硬件测试软件
  4. 【pmcaff】事件营销口碑传播疯传的秘诀在哪里?
  5. java线程数翻倍性能翻倍_术业专攻 | 如何让Java Web性能翻倍?
  6. Python中的ThreadLocal变量
  7. 《从0到1学习Flink》—— 介绍Flink中的Stream Windows
  8. G6 图可视化引擎——核心概念——节点/边/Combo——内置节点——内置节点总览
  9. 火狐SEO插件:查询网站收录与外链的火狐油猴脚本工具
  10. Cloud for Customer UI上点了checkbox后发送到后台的事件
  11. oracle 48小时内_缺血性脑梗死后48小时内使用阿替普酶能够降低脑损伤程度
  12. python的类中包含什么_Python中的类(中)
  13. java读取配置文件中文乱码
  14. java 对错代厔_将汉语转换成拼音,实现拼音和中文双重登录
  15. 机器学习中的Encoder和Decoder到底是什么
  16. html网站设计项目心得,网页设计制作心得体会,网页设计实训报告步骤
  17. 软件开发经验总结(容错性)
  18. 【智能卡】智能卡之SWP
  19. Android verity Boot
  20. 计算机应用基础上机考试,《计算机应用基础》上机考试试题.文件.doc

热门文章

  1. 【无标题】数仓实战之亚马逊全球跨境电商分析平台
  2. 微信资料在电脑上怎么打印?
  3. 一款非常好用且专业的免费万兴数据恢复软件
  4. 微信小程序Canvas绘图API
  5. 4月14日~15日,2021慕尼黑上海电子展,我等你来!
  6. Unity做一个魔方
  7. 解锁Gradio Interface的便捷与扩展性:load、from_pipeline、integrate和queue方法的魔力
  8. 基于人脸识别的门禁系统报告
  9. 像素 英寸 厘米的换算
  10. SQL--数据的过滤和分组