函数防抖(debounce)与函数节流(throttle)都是为了限制函数的执行频次,以优化函数触发频率太高致使的响应速度跟不上触发频率,出现延迟、假死或卡顿的现象。java
1、 函数防抖(debounce)git
概念github
函数防抖(debounce)是指在必定时间内,动做被连续频繁触发的状况下,动做只会被执行一次,也就是说在事件被触发n秒后再执行回调,若是在这n秒内又被触发,则从新计时。app
应用场景异步
对于函数防抖,主要应用场景为如下几种: 1. 给按钮提交函数防抖阻止表单屡次提交 2. 对于输入框连续输入进行AJAX验证时,用函数防抖能有效减小请求次数 3. 判断scroll是否滑到底部,滚动事件+函数防抖 4. 表单验证(用户输入时,验证输入的正确性) -总结来讲,函数防抖适合屡次事件一次响应的状况
源码函数
function debounce(fn, wait) { var timer = null; return function () { var context = this var args = arguments if (timer) { clearTimeout(timer); timer = null; } timer = setTimeout(function () { fn.apply(context, args) }, wait) } }; var fn = function () { console.log('boom') } setInterval(debounce(fn,500),1000) // 第一次在1500ms后触发,以后每1000ms触发一次 setInterval(debounce(fn,2000),1000) // 不会触发一次(我把函数防抖看出技能读条,若是读条没完成就用技能,便会失败并且从新读条)
简单实例fetch
在咱们项目中搜索框,存在用户输入文本,自动联想匹配出一些接口供用户选择,咱们可能首先想到的作法是监听输入框的keyup事件,而后异步去查询结果。可是存在这样的状况,若是用户连续输入n多个字符,那么瞬间就会触发10屡次请求,形成请求浪费。 咱们想要的是用户中止输入的时候才去触发查询的请求,这时候防抖函数就能够帮到咱们。优化
具体代码实现以下this
请输入搜索词:<input type="text" id="search" list="search_list" name=""> <datalist id="search_list"></datalist> (function ($) { var $search = $('#search'); var $search_list = $('#search_list'); var timer = null; //定义定时器 $search.on('keyup', function () { timer && clearTimeout(timer); //若是定时器存在,清除定时器,中断操做 timer = setTimeout(handleChange, 500); //发送异步请求 }); //输入字段改变 function handleChange() { var s = $search.val(); $search_list.empty(); fetchBaiduSuggest(s, function (word, result) { result.map(function (w) { $('<option />').val(w).text(w).appendTo($search_list); }); }); } function fetchBaiduSuggest(word, cb) { $.getJSON("http://suggestion.baidu.com/su?wd=" + encodeURIComponent(word) + "&cb=?", function ( data) { if ($.isArray(data.s)) { cb(word, data.s); } }); } })(jQuery);
2、函数节流spa
函数节流是指必定时间内执行的操做只执行一次,也就是说即预先设定一个执行周期,当调用动做的时刻大于等于执行周期则执行该动做,而后进入下一个新周期,一个比较形象的例子是若是将水龙头拧紧直到水是以水滴的形式流出,那你会发现每隔一段时间,就会有一滴水流出。
应用场景
源码
function throttle(fn, gapTime) { let _lastTime = null; return function () { let _nowTime = new Date() if (_nowTime - _lastTime > gapTime || !_lastTime) { fn(); _lastTime = _nowTime } } } let fn = ()=>{ console.log('boom') } setInterval(throttle(fn,1000),10)
简单实例
若是咱们如今须要作一个记录用户鼠标移动轨迹的小应用,像这种对流畅度有必定的要求的状况,再用上面的防抖函数就不合适了,若是用防抖函数会出现什么效果呢?若是鼠标移动速度较快,那么只有在咱们每次鼠标停下来的时候才能发送当前的位置,可是若是咱们每次移动都发送并记录鼠标的位置,那也是至关恐怖的,鼠标随便移动一下就会有成百上千条记录位置的请求发出去,这个时候咱们就能够用到函数节流,节流顾名思义也就是个一段儿时间去发送一次位置,能够大大减小请求发送次数。
<h2>函数节流</h2> <div> X: <span id='x'></span> Y: <span id='y'></span> </div> <script> (function($){ var $x = $('#x'); var $y = $('#y'); var isRun = true; $(document).on('mousemove',function(event){ var e = event || window.event; if(!isRun) return; // 判断是否已空闲,若是在执行中,则直接return isRun = false; setTimeout(function(){ $x.text(e.pageX); $y.text(e.pageY); isRun = true; },100) }) })(jQuery);
3、总结
函数防抖和函数节流是在时间轴上控制函数的执行次数。函数节流和函数去抖的核心其实就是限制某一个方法被频繁触发,而一个方法之因此会被频繁触发,大多数状况下是由于 DOM 事件的监听回调,而这也是函数节流以及去抖多数状况下的应用场景