阿里面试(你说一下函数防抖和节流……)

今天听同事分享最近写的代码模块,提到了一个名词,_函数节流_
这个词真是熟悉而又陌生的词,上一次看到还是在网上各种流行的前端面试宝典中.
当时我看到这个就像看到蒙娜丽莎的微笑一样神秘而难以琢磨,我果断的跳过了这个题.
没想到时隔半年在项目里看到了同事写了.
想想差距出来从来都不是不经意的(菜鸡感叹),也许就是当你看到这篇文章又顺手划走的时候.
于是我乘着空闲去看了以这到底是是什么,有什么用,在什么场景下使用,如何使用,它的实现原理是什么.
这一次一定要把它研究得明明白白的.
函数节流还有一个孪生兄弟叫做 函数防抖
它两的出现都是为了 _优化高频率执行js代码_.
比如说js中有的一些事件浏览器的resizescroll,鼠标的mousemovemouseoverinputkeypress事件在触发时候都会
不断的调用绑定在事件上的回调函数
这样就是浪费资源,降低性能。所以为了优化体验,就需要对这些事件调用的次数做限制。
概念 函数节流是什么?

每隔一段时间,只执行一次函数
限制了函数再一定时间只能执行一次
就像坐地铁,过闸机时,每个人进入后3秒关闭,才能等下一个人进入
函数防抖
在触发事件的n秒后函数才会被执行,如果n秒内又触发了事件,则会重新重新计算函数执行的时间
简单的说就是一个动作连续触发时,只有最后一次有效。
就像坐公交,司机会等最后一个人上来再关门,每进一个人就会多等待几秒。
原理 如何实现函数节流
函数节流实现的原理是定时器通过定时任务延迟方法的执行,在延时时间内若是方法被触发,就是退出方法,从而实现函数在一段时间内只能执行一次。
  • 函数节流的 setTimeout版简单实现
const _.throttle = (func, wait) => { let timer; return () => { if (timer) { return; }timer = setTimeout(() => { func(); timer = null; }, wait); }; };

【阿里面试(你说一下函数防抖和节流……)】函数节流的目的,是为了限制函数一段时间内只能执行一次
因此,通过使用定时任务,延时方法执行。在延时的时间内,方法若被触发,则直接退出方法。从而,实现函数一段时间内只执行一次
  • 函数节流的时间戳版简单实现
const throttle = (func, wait) => { let last = 0; return () => { const current_time = +new Date(); if (current_time - last > wait) { func.apply(this, arguments); last = +new Date(); } }; };

其实现原理,通过比对上一次执行时间与本次执行时间的时间差与间隔时间的大小关系,来判断是否执行函数。
若时间差大于间隔时间,则立刻执行一次函数。并更新上一次执行时间。
如何是实现函数防抖
const _.debounce = (func, wait) => { let timer; return () => { clearTimeout(timer); timer = setTimeout(func, wait); }; };

函数防抖在执行目标方法时,会等待一段时间。当又执行相同方法时,若前一个定时任务未执行完,则 clear 掉定时任务,重新定时。
应用场景 函数节流常用在需要间隔时间执行一次回调的场景
  • 滚动加载的底部监听,加载更多
  • 搜索框的联想功能
  • 防止按钮重复点击,多次提交表单
函数防抖常用在连续的事件但只需要触发一次的场景
  • 搜索框输入,只需要用户输完再发送请求
  • 手机号和邮箱的输入检查
  • 窗口大小resize,只需要窗口调整完成之后再计算大小
lodash中的 Debounce 、Throttle 当然函数防抖和函数节流那么有用,在lodash里已经有封装好的方法可以直接使用了。
函数节流(throttle)
_.throttle(func, [wait=0], [options=])func (Function): 要节流的函数。 [wait=0] (number): 需要节流的毫秒。 [options=] (Object): 选项对象。 [options.leading=true] (boolean): 指定调用在节流开始前。 [options.trailing=true] (boolean): 指定调用在节流结束后。

如下实际使用示例:
import { throttle } from 'lodash'const THROTTLE_TIME = 300 onClick={throttle(onDownload, THROTTLE_TIME)}

函数防抖(debounce)
_.debounce(func, [wait=0], [options=])func (Function): 要防抖动的函数。 [wait=0] (number): 需要延迟的毫秒数。 [options=] (Object): 选项对象。 [options.leading=false] (boolean): 指定在延迟开始前调用。 [options.maxWait] (number): 设置 func 允许被延迟的最大值。 [options.trailing=true] (boolean): 指定在延迟结束后调用。

    推荐阅读