某些场景下,好比响应鼠标移动或者窗口大小调整的事件,触发频率比较高。若处理函数稍微复杂,须要较多的运算执行时间,响应速度跟不上触发频率,每每会出现延迟,致使假死或者卡顿感。app
为了解决这个问题,咱们只能经过减小执行函数的次数来提升响应速度。函数
throttle 和 debounce 是解决请求和响应速度不匹配问题的两个方案。两者的差别在于选择不一样的策略。this
throttle 等时间间隔执行函数。code
debounce 时间间隔 t 内若再次触发事件,则从新计时,直到中止时间大于或等于 t 才执行函数。事件
/** * * @param fn {Function} 实际要执行的函数 * @param delay {Number} 执行间隔,单位是毫秒(ms) * * @return {Function} 返回一个“节流”函数 */ function throttle(fn, threshhold) { // 记录上次执行的时间 var last // 定时器 var timer // 默认间隔为 250ms threshhold || (threshhold = 250) // 返回的函数,每过 threshhold 毫秒就执行一次 fn 函数 return function () { // 保存函数调用时的上下文和参数,传递给 fn var context = this var args = arguments var now = +new Date() // 若是距离上次执行 fn 函数的时间小于 threshhold,那么就放弃 // 执行 fn,并从新计时 if (last && now < last + threshhold) { clearTimeout(timer) // 保证在当前时间区间结束后,再执行一次 fn timer = setTimeout(function () { last = now fn.apply(context, args) }, threshhold) // 在时间区间的最开始和到达指定间隔的时候执行一次 fn } else { last = now fn.apply(context, args) } } }
调用方法input
$('body').on('mousemove', throttle(function (event) { console.log('tick'); }, 1000));
function debounce(fn, delay) { var timer = null; return function () { var context = this, args = arguments; clearTimeout(timer); timer = setTimeout(function () { fn.apply(context, args); }, delay); }; }
调用方法io
$('input.username').keypress(debounce(function (event) { // do the Ajax request }, 250));