节流

简单版本

const throttle = (fn, interval) => {
    let prev = 0
    return () => {
        const now = Date.now()
        if(now - prev >= interval){
            fn()
            prev = now
        }
    }
}

复杂版

function myThrottle(fn, interval, immediate = true){
    let startTime = 0
 
    const _throttle = function(...args){
        const nowTime = new Date().getTime()
        
        if(!immediate && startTime === 0){
            startTime = nowTime
        }
 
        if(nowTime - startTime >= interval){
            fn.apply(this,args)
            startTime = nowTime
        }
    }
 
    return _throttle
}

防抖

简单版本

const debounce = (fn, delay) => {
    let timer
    return () => {
        if(timer){
            clearTimeout(timer)
        }
        timer = setTime(fn, delay)
    }
}

复杂版

function debounce(fn, delay, immediate = false) {
  // 1.定义一个定时器, 保存上一次的定时器
  let timer = null;
  let isInvoke = false; //记录立即执行是否已执行过
 
  // 2.真正执行的函数
  const _debounce = function (...args) {
    // 取消上一次的定时器
    if (timer) clearTimeout(timer);
 
    // 判断是否需要立即执行
    if (immediate && !isInvoke) {
      fn.apply(this, args);
      isInvoke = true;
    } else {
      // 延迟执行
      timer = setTimeout(() => {
        // 外部传入的真正要执行的函数
        fn.apply(this, args);
 
        //没有这个步骤时,只有第一次输入是立即执行,即使后面延迟执行后再输入也是延迟执行;
        // 有这个步骤时,第一次输入时立即执行,后面延迟执行后再输入也会有立即执行
        isInvoke = false
        timer = null
      }, delay);
    }
  };
 
  return _debounce;
}