炒河粉的无量法师

Trottle 节流函数实现

August 26, 2021JavaScript

虽然节流函数实现这类的文章已经烂大街了,也经常使用源码也看过,但自己亲手实现一边感受又会不一样。当然,此函数并非一气呵成就写出来了,经历了几次使用对比慢慢修正而来。

lodash.trottle 工具方法参数:

参数

  • func (Function): 要节流的函数。
  • [wait=0](number): 需要节流的毫秒。
  • [options=](Object): 选项对象。
  • [options.leading=true](boolean): 指定调用在节流开始前。
  • [options.trailing=true](boolean): 指定调用在节流结束后。

返回

  • (Function): 返回节流的函数。

实现

function throttle(func, wait = 0, options = {}) {
  const { leading = true, trailing = true } = options;
  let timer = null;
  let result;
  let hasTailCall = false;

  const callFunc = function() {
    result = func.apply(null, arguments);
  }
  const cancel = function() {
  	if (timer) {
      clearTimeout(timer);
      timer = null;
      hasTailCall = false;
    }
  };
  
  const returnFunc = function() {
    if (timer) {
      hasTailCall = true;
      return result;
    }
    if (leading) {
      callFunc.apply(null, arguments);
    }
    timer = setTimeout(function() {
      if ((!leading || hasTailCall) && trailing) {
        callFunc.apply(null, arguments);
      }
      timer = null;
      hasTailCall = false;
    }, wait);
    return result;
  };

  returnFunc.flush = function() {
    cancel();
  	callFunc.apply(null, arguments);
    return result;
  };
  returnFunc.cancel = cancel;
  return returnFunc;
}

注意点

如何处理返回值:

每次调用都会有返回值,返回值被存储起来了,每次执行完成之后都会更新。

如何处理 this:

TODO

用例

控制头尾执行时机(leading 和 trailing)

let i = 0;
const fn = throttle(
  function() {
    console.log('this');
    return ++i;
  },
  100,
  // 控制执行时机
  { leading: true, trailing: true }
);

var a = { fn };
console.log(fn(123));
console.log(fn(123));
console.log(fn(123));

setTimeout(function() {
  console.log(fn(123));
  console.log(fn(123));
  console.log(fn(123));
}, 1000);

头尾都执行 leading: true, trailing: true 输出:

this
1
1
1
this
this
3
3
3
this

头执行尾不执行 leading: true, trailing: false 输出:

this
1
1
1
this
2
2
2

头不执行尾执行 leading: false, trailing: true 输出:

undefined
undefined
undefined
this
1
1
1
this

头尾都不执行 leading: false, trailing: false 输出:

undefined
undefined
undefined
undefined
undefined
undefined

野生程序猿,专业铲屎官。#Github 账号