函数节流和函数防抖

小编 2026-06-05 阅读:1905 评论:0
这段时间去面试了两家当前比较拽的互联网公司,回来一总结,广度略有,深度堪忧。这么看来可能觉得还是...

这段时间去面试了两家当前比较拽的互联网公司,回来一总结,广度略有,深度堪忧。这么看来可能觉得还是好事,最近没事在掘金上看看,不知不觉的关注的标签已经有40来个了。

eslint,requirejs,three,Web Components,函数式编程,Visual Studio Code,JSON,TypeScript,vuex,WebAssembly,HTTPS,WebGL,DOM,Canvas,敏捷开发,MVVM,React Native,响应式设计,HTTP,全栈,稀土,电子书,chrome,微信,代码规范,CSS,正则表达式,Node.js, 前端框架, HTML,设计模式,面试,程序员,算法,架构,Webpack......

bla bla bla......

前端就是苦,前端就是累。代码大家都能写,写出什么样的代码,那就是功力。

闲话说的太多了,前端时间自己用vue写了个相当简单的web音乐播放器,写完毕以后一直有几个问题困扰我。

1.vue如何高可用的组件开发。

2.自己写的搜索(autoComplete),返回数据不准确,可能返回以前关键字查询的结果。

3. vuex 如何在错误的时候不阻止程序的继续执行。

 

这里我说的是第二个问题,

我原来的考虑,搜索的时候传递关键字过去, 返回的时候,除了被搜索到的数据,还包括关键字本身。

如果当前的输入框的值和返回的数据的关键字匹配,那么展现,反之丢弃。

这里也有问题,如果关键字前后两次相同,那就会数据填充两次。比如关键字为  a->b->a,第一个a落后于b返回。但至少保证了展现的数据是自己期望的数据。

 

后来看了一下

百度的搜索,也是每次都发送请求,但是一些前面发送的请求会被取消掉,返回html和脚本

bing的搜索,也是每次都发送请求,没有取消,返回数据,html和脚本。

搜狗,每次发送请求,没有取消,返回的是数据+脚本。

但是都一个特点,就是返回的都足够快,这就有点尴尬了。

 

回头再看看自己搜索的问题,才发现问题的是自己的逻辑处理问题

1.当字符为空的时候没有发请求但是没有清空数据

2.oninput,focus处理有问题

 

晕死,一天在掘金看到函数节流和函数防抖,本事想应用到这个及时搜索上面来,可是啊哈,走歪了。

回归,我们来说说函数节流和函数防抖。

 

函数节流 & 函数防抖

Throttling enforces a maximum number of times a function can be called over time. As in "execute this function at most once every 100 milliseconds".

Debouncing enforces that a function not be called again until a certain amount of time has passed without it being called. As in "execute this function only if 100 milliseconds have passed without it being called".

函数节流:是确保函数特定的时间内至多执行一次

函数防抖:是函数在特定的时间内不被再调用后执行

 

函数节流underscore的实现(解释,借用的是JS魔法堂:函数节流(throttle)与函数去抖(debounce))

.throttle = function(func, wait, options) {    /* options的默认值     *  表示首次调用返回值方法时,会马上调用func;否则仅会记录当前时刻,当第二次调用的时间间隔超过wait时,才调用func。     *  options.leading = true;     * 表示当调用方法时,未到达wait指定的时间间隔,则启动计时器延迟调用func函数,若后续在既未达到wait指定的时间间隔和func函数又未被调用的情况下调用返回值方法,则被调用请求将被丢弃。     *  options.trailing = true;      * 注意:当options.trailing = false时,效果与上面的简单实现效果相同     */    var context, args, result;    var timeout = null;    var previous = 0;    if (!options) options = {};    var later = function() {      previous = options.leading === false ? 0 : _.now();      timeout = null;      result = func.apply(context, args);      if (!timeout) context = args = null;    };    return function() {      var now = _.now();      if (!previous && options.leading === false) previous = now;      // 计算剩余时间      var remaining = wait - (now - previous);      context = this;      args = arguments;      // 当到达wait指定的时间间隔,则调用func函数      // 精彩之处:按理来说remaining <= 0已经足够证明已经到达wait的时间间隔,但这里还考虑到假如客户端修改了系统时间则马上执行func函数。      if (remaining <= 0 || remaining > wait) {        // 由于setTimeout存在最小时间精度问题,因此会存在到达wait的时间间隔,但之前设置的setTimeout操作还没被执行,因此为保险起见,这里先清理setTimeout操作        if (timeout) {          clearTimeout(timeout);          timeout = null;        }        previous = now;        result = func.apply(context, args);        if (!timeout) context = args = null;      } else if (!timeout && options.trailing !== false) {        // options.trailing=true时,延时执行func函数        timeout = setTimeout(later, remaining);      }      return result;    };  };

 

函数防抖在underscore的实现,其基本思路,就是内部计时,达到指定时间,就执行,不然启用延时。

_.debounce = function(func, wait, immediate) {    // immediate默认为false    var timeout, args, context, timestamp, result;    var later = function() {      // 当wait指定的时间间隔期间多次调用_.debounce返回的函数,则会不断更新timestamp的值,导致last < wait && last >= 0一直为true,从而不断启动新的计时器延时执行func      var last = _.now() - timestamp;      if (last < wait && last >= 0) {        timeout = setTimeout(later, wait - last);      } else {        timeout = null;        if (!immediate) {          result = func.apply(context, args);          if (!timeout) context = args = null;        }      }    };    return function() {      context = this;      args = arguments;      timestamp = _.now();      // 第一次调用该方法时,且immediate为true,则调用func函数      var callNow = immediate && !timeout;      // 在wait指定的时间间隔内首次调用该方法,则启动计时器定时调用func函数      if (!timeout) timeout = setTimeout(later, wait);      if (callNow) {        result = func.apply(context, args);        context = args = null;      }      return result;    };  };

 

那么应用场景:

函数节流(throttle

1. 频繁的mousemove/keydown,比如高频的鼠标移动,游戏射击类的

2. 搜索联想(keyup)

3. 进度条(我们可能不需要高频的更新进度)

4. 拖拽的dragover等

5.  高频的点击,抽奖等(哈哈,邪恶)

 

函数防抖(debounce

 1. scroll/resize事件

 2. 文本连续输入,ajax验证/关键字搜索

参考:

函数节流去抖与函数柯里化

浅谈 Underscore.js 中 _.throttle 和 _.debounce 的差异

JS魔法堂:函数节流(throttle)与函数去抖(debounce)

 The Difference Between Throttling and Debouncing

Javascript 函数节流和函数去抖场景介绍

版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
标签列表