/**
 * 返回一个自带节流效果的函数，用res表示。
 * 
 * fn：需要被节流的函数
 * interval：最短多长时间允许执行一次fn
 * 
 * 功能要点：
 * 1.fn代码里如有this，res被执行时，this会指向res的调用者；
 * 2.res被执行时的实参会映射到fn的形参；
 * 3.第一次调用res时，会立即执行fn。
 */
 export function throttle(fn, interval) {
  let lastRunTime = 0

  return function (...args) {
    let elapsedTime = Date.now() - lastRunTime
    if (elapsedTime < interval) {
      return
    }

    let context = this
    lastRunTime = Date.now()
    fn.apply(context, args)
  }
}

/**
 * 返回一个自带消抖效果的函数，用res表示。
 * 
 * fn: 需要被消抖的函数
 * delay: 消抖时长
 * isImmediateCall: 是在第一次调用时立即执行fn，还是在最后一次调用后等delay时长再调用fn
 */
export function debounce(fn, delay, isImmediateCall = false) {
  let timer = null
  // 上次调用的时刻
  let lastCallTime = 0

  if (isImmediateCall) {
    return function (...args) {
      const context = this
      const currentTime = Date.now()
      if (currentTime - lastCallTime >= delay) {
        fn.apply(context, args)
      }
      lastCallTime = currentTime
    }
  } else {
    return function (...args) {
      if (timer) {
        clearTimeout(timer)
      }
      const context = this
      timer = setTimeout(() => {
        fn.apply(context, args)
      }, delay)
    }
  }
}