乐趣区

关于javascript:两句话说清楚js的节流与防抖

为什么你还不了解 js 中 函数的节流和防抖 是干嘛的?不怪你。起因有二,一是这两个名字是间接翻译的英文 节流(throttle)防抖(debounce),光听名字就曾经不知所云了。二是太多的文章太啰嗦,让人找不到重点,使浏览变得艰难。

为什么须要节流和防抖?
都是为了避免函数频繁的执行。比方:
节流(throttle)解决以下场景:
1. 鼠标一直点击触发,mousedown(单位工夫内只触发一次)
2. 上拉触底加载更多

防抖(debounce)解决以下场景:
1.search 搜寻联想,用户在一直输出值时,用防抖来节约 ajax 申请。
2. 滚动条滚动的时候触发事件

所以你不必管它是什么意思,记住应用场景就行了。

间接上代码:
节流(throttle):

// 模仿发送申请的 function
const send = (...args) => {console.log(...args);
  console.log("发送申请");
};

const throttle = (fn, time) => {
  let timer = null;
  // 这里用到了闭包,被长久化的局部变量就是定时器 timer
  return (...args) => {if (timer) return;
    fn.call(undefined, ...args);
    timer = setTimeout(() => {timer = null;}, time);
  };
};
// 模仿点击按钮的 function
const click = throttle(send, 5 * 1000);

click(1, 2);

第一次调用点击事件 click,timer=null,fn(就是 send 函数)执行,在 5s 中之内再次调用 click 函数,因为 timer 不为空,就在 if 那里间接 return 了。这就实现了上文所提的场景。

防抖(debounce):

// 模仿发送申请的 function
const sendAjax = (...args) => {console.log(...args);
  console.log("查找");
};

const debounce = (fn, time) => {
  let timer = null;
  // 这里用到了闭包,被长久化的局部变量就是定时器 timer
  return (...args) => {if (timer !== null) {clearTimeout(timer);
    }
    timer = setTimeout(() => {fn.call(undefined, ...args);
    }, time);
  };
};
// 这里是搜寻栏变动执行的 function
const search = debounce(sendAjax, 3 * 1000);

search(1,2);

当搜寻框内容变动的时候执行了 search 函数,这个时候创立了一个 3s 的定时器 timer,当在 3s 内用户再次输出内容又会触发 search 函数,这时候 timer 不为空,进入 if,执行 clearTimeout,革除定时器,而后在从新生成一个 3s 的 timer。这样就实现了上文中所说的场景。

弄清楚这个逻辑之后,实现上就很容易了。惟一可能造成困惑的点就是‘闭包了’,如果有这个困惑,能够看我另一篇对于闭包的文章。

退出移动版