为了完整阅读体验,欢迎移步到个人博客原文。css
防抖(去抖),以及节流(分流)在平常开发中可能用的很少,但在特定场景,却十分有用。本文主要讨论防抖,镜像文章:节流 - 理解,实践与实现。分开讨论防抖和节流,主要是为了让一些还不太了解防抖节流的读者可以有针对性地,逐一掌握它们。
防抖有两种模式(容易让人迷惑):延时执行和直接执行。后续详细讨论。
防抖还有一个关键点是若是用代码实现。本文以按部就班地方式,先以实现一个简单案例为例,绘制流程图,再根据流程图逻辑编写防抖功能代码。html
以平常开发中经常使用的搜索按钮为例,若用户点击一次搜索按钮后,不当心“手抖”很快又点了一次按钮,防抖能够规避第二次甚至更屡次搜索。前端
点击查看案例git
第一个搜索按钮未作任何防抖处理。
搜索按钮A为第一种防抖模式:延时执行。若用户连续快速点击屡次,只有最后一次点击结束,延时一段时间后才执行搜索。
搜索按钮B为第二种防抖模式:直接执行。若用户连续快速点击屡次,只有第一次点击会执行搜索。github
结合上方案例,防抖能够理解为:屡次触发事件后,事件处理函数只执行一次。
而防抖的两种模式能够根据实际使用场景分别应用。segmentfault
在搜索框中实时键入文本搜索app
点击查看案例函数
防止频繁点击搜索按钮触发搜索请求
点击查看案例测试
接下来咱们经过一个案例梳理实现防抖的思路。
假设咱们要实现本文第一个案例中搜索按钮A的功能。首先整理需求:this
实现的方法有两种,推荐第一种,用计时器(setTimeout)简化代码,将重心放在实现防抖的逻辑上。
方法一核心参数:
绘制方法一的流程图:
根据流程图思路实现方法一的防抖代码:
function debounce( func, wait = 0 ) { let timer function debounced( ...args ) { const self = this if ( timer == null ) { addTimer() return } if ( timer != null ) { clearTimer() addTimer() return } function addTimer() { timer = setTimeout( () => { invokeFunc() clearTimer() }, wait ) } function invokeFunc() { func.apply( self, args ) } } return debounced function clearTimer() { clearTimeout( timer ) timer = null } }
方法二核心参数:
绘制方法二的流程图:
根据流程图实现方法二的防抖代码:
function debounce( func, wait = 0 ) { // Earliest time when func can be invoked let earliest function debounced( ...args ) { const self = this if ( typeof earliest === 'undefined' ) { setEarliset() } if ( typeof earliest !== 'undefined' ) { if ( now() >= earliest ) { invokeFun() } else { setEarliset() } } function setEarliset() { earliest = now() + wait } function invokeFun() { func.apply( self, args ) } } return debounced function now() { return +new Date() } }
一样,咱们可使用相似方法实现搜索按钮B的功能。
需求描述:
核心参数:
function debounce( func, wait = 0 ) { let timer function debounced( ...args ) { const self = this timer == null && invokeFunc() timer != null && clearTimer() timer = setTimeout( clearTimer, wait ) function invokeFunc() { func.apply( self, args ) } } return debounced function clearTimer() { clearTimeout( timer ) timer = null } }
接下来咱们使用刚才编写的debounce函数来测试第一个案例
点击查看案例
防抖是一个高阶函数,可以将多个事件函数合并为一个,在“调整window尺寸”,“在搜索框中实时搜索键入文本”, “滚动滚动条”和“防止搜索按钮频繁点击触发多余请求”等案例中,十分有用。
感谢你花时间阅读这篇文章。若是你喜欢这篇文章,欢迎点赞、收藏和分享,让更多的人看到这篇文章,这也是对我最大的鼓励和支持!
同时欢迎阅读个人更多原创前端技术博客: 苏溪云的博客。