函数节流与函数防抖

函数节流(throttle)

函数节流:在指定的间隔时间内只执行一次
有个须要频繁触发函数,出于优化性能角度,在规定时间内,只让函数触发的第一次生效,后面不生效。
好比下面的例子,在不加函数节流的时候,每当滚动条滚动的时候都会触发一次,形成大量的性能浪费闭包

// 未添加节流函数
document.onscroll = function () {
  console.log('scroll事件被触发了')
}

添加了节流函数后app

// 添加了节流函数
document.onscroll = throttle(function () {
  console.log('scroll事件被触发了')
}, 300)


具体代码实现函数

/**
 * @description 函数节流
 * @param {Function} fn 须要执行函数节流的函数
 * @param {Number} interval 指定间隔时间
 */
function throttle(fn, interval = 300) {
  let canRun = true // 经过闭包保存一个标记
  return function () {
    if (!canRun) return // 第一次调用执行
    canRun = false // setTimeout未执行时,后续fn函数调用都不会再执行
    // setTimeout 定时器延时执行
    setTimeout(() => {
      fn.apply(this, arguments)
      canRun = true // 标记为true,节流完成
    }, interval)
  }
}

代码解释
简单来讲,函数的节流就是经过闭包保存一个标记(canRun = true), 在函数的开头判断这个标记是否为true,若是这个标记为true的话就继续执行,不然就return掉,判断完标记后当即把这个标记设置为false,而后把外部传入的函数的执行包在一个setTimout中,最后在定时器执行完毕以后再把标记设置为true,表示本次延迟执行完毕,能够执行下一次循环了。当定时器还未执行完毕的时候,canRun这个标记始终未false,故在开头的判断中老是被return掉,函数并未执行。、
应用场景
监听滚动事件判断是否到页面底部自动加载更多:给 scroll 加了 debounce 后,只有用户中止滚动后,才会判断是否到了页面底部;若是是 throttle 的话,只要页面滚动就会间隔一段时间判断一次等性能

函数防抖(debounce)

函数防抖: 一个须要频繁触发的函数,在规定时间内,只让最后一次生效,前面的不生效。
好比点击一个按钮,每点击一次就会触发一次事件,在没有加防抖函数的状况下,快速点击会致使屡次触发优化

// 未加防抖函数
document.getElementById('btn').onclick = function(){
  console.log('我被点击了');
}

在加了防抖函数后,只会在规定时间后触发一次this

// 加了防抖函数
document.getElementById('btn').onclick = debounce(function(){
  console.log('我被点击了');
},300)

具体代码实现code

/**
 * @description 函数防抖
 * @param {Function} fn 须要执行函数防抖的函数
 * @param {Number} interval 指定间隔时间
 */
function debounce(fn, interval = 300) {
  let timeout = null // 经过闭包保存一个标记
  return function () {
    clearInterval() // 把前一个定时器去掉
    // 又建立一个新的定时器
    timeout = setTimeout(() => {
      fn.apply(this, arguments) // 指定的时间间隔以后运行fn
    }, interval)
  }
}

代码解释
其原理就第一次调用函数,建立一个定时器,在指定的时间间隔以后运行代码。当第二次调用该函数时,它会清除前一次的定时器并设置另外一个。若是前一个定时器已经执行过了,这个操做就没有任何意义。然而,若是前一个定时器还没有执行,其实就是将其替换为一个新的定时器,而后延迟必定时间再执行。
应用场景
文本输入的验证(连续输入文字后发送 AJAX 请求进行验证,验证一次就好)blog

相关文章
相关标签/搜索