[关闭]
@Dale-Lin 2020-05-05T19:26:05.000000Z 字数 1562 阅读 631

节流/防抖/分时/惰性加载

JavaScript


概念

应用

节流

实现

节流(throttle)

通过闭包 + setTimeout,保存一个能否执行的 token,如果不可执行,则 return;否则执行。执行语句最后应该将 token 改为可执行。

  1. function throttle(fn, interval = 500) {
  2. const _fn = fn;
  3. let timer, firstTime = true;
  4. return function(...args) {
  5. const that = this;
  6. if (firstTime) {
  7. _fn.call(that, ...args);
  8. firstTime = false;
  9. return;
  10. }
  11. if (timer) {
  12. return;
  13. }
  14. timer = setTimeout(() => {
  15. timer = null;
  16. _fn.call(that, ...args);
  17. }, interval)
  18. }
  19. }

防抖

通过闭包,保存一个标记 setTimeout 的值,每次输入时 clearTimeout 已有值,重新 setTimeout。这样就能保证输入字符后的 interval 内触发时,不重复执行。

  1. function debounce(func, wait) {
  2. const _fn = func;
  3. let time;
  4. return function(...args) {
  5. const that = this;
  6. clearTimeout(time);
  7. time = setTimeout(() => {_fn.apply(this, args)}, wait)
  8. }
  9. }

区别

区别是,防抖(debounce)会重新计算间隔时间;而节流(throttle)没有清空计时器,故不会重新计算间隔时间

分时

短时间内向页面中添加大量的 DOM 节点会导致浏览器卡顿或假死。
分时函数用来控制一定时间内的处理数量。
第一个参数是数据集合,第二个是创建添加节点的函数,第三个是每一次创建节点的数量:

  1. const timeChunk = (arr, fn, count = 8) => {
  2. let t;
  3. const createNode = () => {
  4. for (let i = 0; i < Math.min(count, len); i++) {
  5. const obj = arr.shift();
  6. fn(obj);
  7. }
  8. }
  9. return () => {
  10. t = setInterval(() => {
  11. if (arr.length === 0) return clearInterval(t);
  12. createNode();
  13. }, 200);
  14. };
  15. };

创建好后清除计时器,也可以手动修改间隔时间等参数。

惰性加载函数

开发中因为浏览器之间的差异,一些嗅探工作不可避免,addEventListener 和 attachEvent 的区别。

需要注意的是这些嗅探其实只需要执行一次就可以了,通过在函数内部重写嗅探结果得出的函数(不能用 const 声明了)可以实现惰性加载的函数:

  1. let addEvent = function(ele, type, handler) {
  2. if (window.addEventListener) {
  3. addEvent = function(ele, type, handler) {
  4. ele.addEventListener(type, handler, false);
  5. }
  6. } else if (window.attachEvent) {
  7. addEvent = function (ele, type, handler) {
  8. ele.attachEvent(`on${type}`, handler);
  9. }
  10. }
  11. addEvent(ele, type, handler);
  12. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注