摘要:封装方法也比较简单,书中对此问题也进行了处理使用定时器,让函数延迟秒后执行,在此秒内,然后函数再次被调用,则删除上次的定时器,取消上次调用的队列任务,重新设置定时器。
在实际开发中,函数一定是最实用最频繁的一部分,无论是以函数为核心的函数式编程,还是更多人选择的面向对象式的编程,都会有函数的身影,所以对函数进行深入的研究是非常有必要的。
函数节流比较直白的说,函数节流就是强制规定一个函数在一段时间内能够被执行的最大次数,比如,规定某个函数在每100毫秒的时间段内,最多被执行一次,那么对应的在10s(10000ms)内,最多就会执行100(10000ms/100ms)次
这里节流和防抖的概念比较容易搞混,所以文中许多关键性定义,参考此处文档翻译过来,移步到the-difference-between-throttling-and-debouncing
在浏览器中,频繁的DOM操作非常消耗内存和CPU时间,比如监听了resize,touchmove,scroll...等事件,在dom改变时都会不断触发回调。现在的react 和 vue 等前端框架都提出了虚拟DOM的概念,会把多次DOM操作合并到一次真实操作中,就是使用了Diff算法,这样就大大减低了DOM操作的频次。但是,这里并不是要讨论diff算法,如果感兴趣可以戳上面的链接,而是解释如何利用setTimeout来减低DOM频繁操作的风险。
最早接触到这个概念的时候,是在《高程3》最后几章上面。
函数节流背后的基本思想是指,某些代码不可以在没有间断的情况下连续重复执行.第一次调用函数,创建了一个定时器,在指定的时间间隔之后运行代码。当第二次调用该函数时,它会清除前一次的定时器并设置另一个。
封装方法也比较简单,书中对此问题也进行了处理:
function throttle(method,context) { clearTimeout(method.tId); method.tId = setTimeout(function(){ method.call(context) },1000) }
使用定时器,让函数延迟1秒后执行,在此1秒内,然后throttle函数再次被调用,则删除上次的定时器,取消上次调用的队列任务,重新设置定时器。这样就可以保证1秒内函数只会被触发一次,达到了函数节流的目的
可以利用 resize事件测试一下;
var i = 0; function handler(){ console.log(i++); } window.onresize = function(){ throttle(handler,window) }
可以发现,在浏览器的调试模式下,切换横屏/竖屏,只触发了一次
函数防抖函数防抖 规定函数再次执行需要满足两个条件:
1,必须要等待一段时间;
2,在条件1等待的时间段内不再被触发,一旦在条件1等待的时间内再次被触发,等待时间就要重新开始计算。
比如:对一个函数加了100ms的防抖操作,然后在3s(3000ms)时间段内,这个函数被不连续的调用了1000次,3s后停止调用。 它只会在3100ms的时刻执行一次。
具体实现代码,看下 underscore.js中的 _.debounce 源码:
// Returns a function, that, as long as it continues to be invoked, will not // be triggered. The function will be called after it stops being called for // N milliseconds. If `immediate` is passed, trigger the function on the // leading edge, instead of the trailing. _.debounce = function(func, wait, immediate) { var timeout, args, context, timestamp, result; var later = function() { 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(); var callNow = immediate && !timeout; if (!timeout) timeout = setTimeout(later, wait); if (callNow) { result = func.apply(context, args); context = args = null; } return result; }; };
wait参数代表debounce时间, _.now()返回当前时间的时间戳,同样以ms 为单位。 如果传入了 immediate,会立即触发回调函数。
应用场景:
在使用高德地址联想输入提示时,只有在用户停止键盘输入时,才去进行ajax请求
elementUI inputNumber计算器组件中,为了防止用户多次点击,数字自动增减,也使用了防抖操作,有兴趣可以查看源码
参考资料:
the-difference-between-throttling-and-debouncing
浅谈javascript的函数节流(腾讯全端 AlloyTeam 团队 Blog)
JavaScript 函数节流
函数防抖与节流
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/92254.html
摘要:文章来源详谈防抖和节流轻松理解函数节流和函数防抖函数防抖和节流好啦,今天的小菊花课堂之的防抖与节流的内容就告一段落啦,感各位能耐心看到这里。 前言 陆游有一首《冬夜读书示子聿》——古人学问无遗力,少壮工夫老始成。纸上得来终觉浅,绝知此事要躬行。,其中的意思想必大家都能明白,在学习或工作中,不断的印证着这首诗的内涵。所以,又有了此篇小菊花文章。 详解 在前端开发中,我们经常会碰到一些会持...
摘要:文章来源详谈防抖和节流轻松理解函数节流和函数防抖函数防抖和节流好啦,今天的小菊花课堂之的防抖与节流的内容就告一段落啦,感各位能耐心看到这里。 前言 陆游有一首《冬夜读书示子聿》——古人学问无遗力,少壮工夫老始成。纸上得来终觉浅,绝知此事要躬行。,其中的意思想必大家都能明白,在学习或工作中,不断的印证着这首诗的内涵。所以,又有了此篇小菊花文章。 详解 在前端开发中,我们经常会碰到一些会持...
摘要:函数防抖简单实现模拟请求获取函数的作用域和变量清除定时器节流名词解释连续执行函数,每隔一定时间执行函数。效果函数防抖是某一段时间内只执行一次函数节流是间隔时间执行,不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数。 防抖(debounce) 名词解释:在事件被触发n秒后再执行回调函数,如果在这n秒内又被触发,则重新计时。 使用场景:以百度输入框例,比如你要查询...
摘要:隆重请出主角防抖与节流。防抖与节流的异同相同都是防止某一时间段内,函数被频繁调用执行,通过时间频率控制,减少回调函数执行次数,来实现相关性能优化。参考文章分钟理解的节流防抖及使用场景函数防抖和节流 showImg(https://segmentfault.com/img/bVburM8?w=800&h=600); 本篇课题,或许早已是烂大街的解读文章。不过春招系列面试下来,不少伙伴们还...
摘要:防抖与节流源码学习最近自己撸了一个轮播图,在点击切换的时候,为了寻求更好的用户体验,引入了节流,在此记录对源码的学习过程源码来源防抖函数防抖使用场景现在我们需要做一个搜索框,当用户输入文字,执行事件的时候,需要发出异步请求去进行结果查询。 防抖与节流(源码学习) 最近自己撸了一个轮播图,在点击切换的时候,为了寻求更好的用户体验,引入了节流,在此记录对源码的学习过程源码来源:unders...
阅读 3791·2021-11-12 10:34
阅读 2811·2021-09-22 15:14
阅读 776·2019-08-30 15:53
阅读 3194·2019-08-30 12:53
阅读 1278·2019-08-29 18:32
阅读 2760·2019-08-29 16:41
阅读 1055·2019-08-26 13:40
阅读 1794·2019-08-23 18:07