函数节流 throttle and debounce的相关总结及想法javascript
一开始函数节流的使用场景是:放止一个按钮屡次点击屡次触发一个功能函数,因此作了一个clearTimeout setTimeout函数java
clearTimeout(cancelTimer); cancelTimer =setTimeout(function(){ switchControl.switchAciontFactory(view, conf); },300)
代码的意思就不作多说了,实际上我无心间实现了一个debounce
在underscore.js中对于节流函数有两种定义
trottle:若定义初始间隔100ms,屡次触发事件只会触发初始的那一次,事件会与第一次触发的100ms后调起
debounce:对于间隔时间内100ms内发生的调起事件,会不断重置setTimeout的时间
下面来一段trorrle的源码
_.throttle = function(func, wait, options) { var context, args, result; var timeout = null; // 上次执行时间点 var previous = 0; if (!options) options = {}; // 延迟执行函数 var later = function() { // 若设定了开始边界不执行选项,上次执行时间始终为0 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; // 延迟时间间隔remaining小于等于0,表示上次执行至此所间隔时间已经超过一个时间窗口 // remaining大于时间窗口wait,表示客户端系统时间被调整过 if (remaining <= 0 || remaining > wait) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); if (!timeout) context = args = null; //若是延迟执行不存在,且没有设定结尾边界不执行选项 } else if (!timeout && options.trailing !== false) { timeout = setTimeout(later, remaining); } return result; }; };
它其实是经过一个计算,每次触发这个函数的时候获取当前时间,经过与上次存取的时间做对比,计算差值,动态设置setimeout的值,但实际我的以为作一个阻断log就okapp
function throttle(fuc,wait){ if(typeof(changeLog) == 'undefined'){ setTimeout(fuc,wait) window.changeLog = true } }
固然弊端不言而喻,全局声明的变量污染函数
再去观看debounce的源码,相同的作法可是很奇怪的是,他没有果断重置setTimeout的时间,而是经过时间差值的加减,反正没看出有什么好处。。。this