防抖和节流

209 阅读2分钟

防抖(debounce)

示例展示

当持续触发事件时,一定时间段内没有再触发事件,时间处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。

使用场景

  • 非立即执行:search搜索联想,用户在不断的输入值时,用防抖来节约请求资源;
  • 立即执行:表单提交按钮点击,用户多次点击提交按钮,防止多次提交表单 代码
// 防抖 非立即执行版
  const debounce = () => {
    let timeout = null; // 用来存放延迟器的返回值
    return function(e) {
      clearTimeout(timeout);// 清除上一次的延迟器
      timeout = setTimeout(() => { // 创建一个新的延迟器
        console.log('执行')
      }, 500)
    }
  }

  // 防抖 立即执行
  function debounce(){
    let timeout = null; // 用来存放延迟器的返回值
    return (e)=>{
      if (!timeout) {// 如果没有延迟器就执行
         console.log('执行')
      }
      clearTimeout(timeout) // 清除上一次的延迟器
      timeout = setTimeout(() => { // 创建一个新的延迟器
        timeout = null // 进行重新赋值
      }, 500)
    }
  }

节流(throttle)

示例展示

当持续触发事件时,保证一定时间段内只调用一次事件处理函数。

使用场景

  • 监听滚动事件,比如是否滑到底部自动加载更多; 代码
  // 节流 时间戳版
  const throttle =()=>{
    let timestamp = 0;// 设置时间戳标记
    return (e)=>{
      const nowTime = Date.now() // 获取当前时间戳
      if (nowTime-timer>500) { // 当前时间和标记进行对比
        console.log('执行')
        timer=Date.now()  // 执行后进行标记赋值
      }
    }
  } 

  // 节流 时间戳版
  const throttle =()=>{
    let canRun = true;// 闭包保存一个标记
    return ()=>{
      if (canRun) {// 如果标记为true执行
        canRun=false // 改变状态赋值为false
        setTimeout(() => {
          console.log('执行')
          canRun = true // 改变状态赋值为true 可以执行下一次循环
        }, 500);
      }
    }
  }

注:文中若有问题留言或私信联系