chiyan-lin / code-snippet

the record of something snippety
1 stars 0 forks source link

debounce and throttle #7

Open chiyan-lin opened 4 years ago

chiyan-lin commented 4 years ago
/**
 * 防抖:触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间
 *
 * 节流:高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率
 *
 */

function debounce (fn, wait = 1000) {
  let timer = null
  return function () {
      clearTimeout(timer)
      timer = setTimeout(() => {
          fn.apply(this, arguments)
      }, wait)
  }
}

function debounce (func, wait, immediate) {
  var timer, result

  var debounced = function () {
    var context = this
    var args = arguments

    if (timer) clearTimeout(timer)
    if (immediate) {
      // 如果已经执行过,不再执行
      var callNow = !timer
      timer = setTimeout(function () {
        timer = null
      }, wait)
      if (callNow) result = func.apply(context, args)
    } else {
      timer = setTimeout(function () {
        func.apply(context, args)
      }, wait)
    }
    return result
  }

  debounced.cancel = function () {
    clearTimeout(timer)
    timer = null
  }

  return debounced
}

function throttle(fn, wait = 1000) {
  let timer
  return function () {
    if (!timer) {
      timer = setTimeout(() => {
        clearTimeout(timer)
        fn.apply(this, arguments)
      }, wait)
    }
  }
}

function throttle (func, wait, options) {
  var timer
  var previous = 0
  if (!options) options = {}

  throttled.cancel = function () {
    if (timer) {
      clearTimeout(timer)
      timer = null
    }
  }

  var throttled = function () {
    var now = +new Date()
    if (!previous && options.leading === false) previous = now
    var remaining = wait - (now - previous)
    if (remaining <= 0) {
      throttled.cancel()
      previous = now
      func.apply(this, arguments)
    } else if (!timer && options.trailing !== false) {
      timer = setTimeout(() => {
        throttled.cancel()
        previous = options.leading === false ? 0 : +new Date()
        func.apply(this, arguments)
      }, remaining)
    }
  }
  return throttled
}