函数节流与函数防抖

函数节流

规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。

适用场景:实现图片懒加载时,给窗口滚动事件挂载回调。其实并不需要实时不断地执行该函数,每200ms执行一次足矣。

/**
 * [throttle 函数节流]
 * @param  {Function} fn      [需要进行函数节流的函数]
 * @param  {Number}   wait    [函数执行的时间间隔]
 */
function throttle(fn, wait) {
  let canRun = true // 首次可执行
  return function execute () {
    if (!canRun) return // 若是false,此处则阻挡
    canRun = false // 方法执行前先设置为false,此时若再触发,则会被挡在前面的判断
    setTimeout(() => { // 规定时间后执行真正的方法fn
      fn.apply(this, arguments)
      canRun = true // 执行完后设置会true, 以便下次可执行
    }, wait)
  }
}

// 应用示例
function cll() {
  console.log(window.scrollY)
}

window.onscroll = throttle(cll, 1000)

函数防抖

在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。

适用场景:搜索框输入关键词后,调取API获取联想词。用户输入停止500ms后再触发回调。

/**
 * [debounce 函数防抖]
 * @param  {Function}  fn        [需要进行函数防抖的函数]
 * @param  {Number}    wait      [需要等待的时间]
 * @param  {Boolean}   immediate [调用时是否立即执行一次]
 */

const debounce = (fn, wait, immediate) => {
  let timeout = null
  return function () {
    if (immediate) { // 事件触发时可立即执行一次
      fn.apply(this, arguments)
      immediate = false // 之后都不再立即触发,此if代码块只执行一次。
    } else {
      clearTimeout(timeout) // 事件不断触发的过程中不断地取消上一个定时器,下面会重新定时。
      timeout = setTimeout(() => { // 只有当触发间隔时间超过设定值wait,才有机会执行。否则会被clearTimeout取消掉。但无论如何,最后一次事件触发后最终都会执行一次。
        fn.apply(this, arguments)
      }, wait)
    }
  }
}

const requestHotWords = value => {
  // 请求API获取相关热搜词
  console.log('=xu=你输入的关键词是', value)
}

const myDelay = debounce(requestHotWords, 1000, false)

myDelay({value: '总监'}) // 1秒后输出:=xu=你输入的关键词是 总监
View Code

或者

const inputEvent = (e) => {
  debounce(requestHotWords, 1000, null, e.value)
}

const debounce = (fn, delay, context, value) => {
  clearTimeout(fn.timeoutId)
  fn.timeoutId = setTimeout(() => {
    fn.call(context, value)
  }, delay)
}

const requestHotWords = value => {
  // 请求API获取相关热搜词
  console.log('=xu=你输入的关键词是', value)
}

inputEvent({value: '总监'}) // 1秒后输出:=xu=你输入的关键词是 总监
View Code

 

posted on 2019-03-12 22:05  dawnxuuu  阅读(131)  评论(0编辑  收藏  举报

导航