面试时手写节流函数

119 阅读2分钟

本文已参与[新人创作礼]活动,一起开启掘金创作之路。

节流函数:

需要频繁触发的函数 在设定的规定时间内,只执行一次,后面的触发要等间隔时间完后才能执行

使用场景:

  • 监听滚动事件:例如滑动滚轮,就需要用到节流函数,限制在一定时间间隔内才去执行相应的函数
  • input输入:input进行搜索时请求后端接口,每隔一段时间去发送请求接口

自定义节流函数:

1. 利用时间戳

定义一个初始化事件的时间,在内部函数中 定义当前时间,然后去判断两次时间的间隔,如果间隔时间大约我们指定的时间,则执行我们指定的函数,在此例中,我们监听document.onscroll函数,当我们不断滑动鼠标滚轮,间隔500ms才会打印一下结果

// 节流的实现1;
export function throttle(fn, delay = 500) {
  let curTime = Date.now(); //// 初始化事件开始的时间为0

  return function (args) {
    let nowTime = Date.now(); // 获取当前的时间

    // 如果两次时间间隔超过了指定时间,则执行函数。
    if (nowTime - curTime >= delay) {
      console.log("this", this);
      curTime = nowTime; //让下次的对比时间变成此次的当前时间
      return fn.apply(this, [args]);
    }
  };
}
export default function ThrottleFc() {
  document.onscroll = throttle(function () {
    console.log("throttle函数执行了" + Date.now());
  }, 600);
  return <div style={{ height: 2000 }}>11111111111111111111</div>;
}

实现效果:

image.png

2. 利用setTimeout:

先定义一个定时器,在内部函数中若没有定时器,说明上一次设定的定时器已到时销毁,若上次定时器时间还没到 ,就不执行相应函数

// 节流的实现2;
export const throttle2 = (fn, wait = 500) => {
  let timeout; //定义一个定时器
  return function (args) {
    // 若没有定时器,说明上一次设定的定时器已到时销毁,若上次定时器时间还没到 ,就不执行相应函数
    if (!timeout) {
      timeout = setTimeout(function () {
        console.log("this", this);
        fn.apply(this, [args]);
        timeout = null;
      }, wait);
    }
  };
};

若文中有误,望大佬指出