Skip to content

throttle

节流函数

参数

参数名参数类型参数说明
fnany指定的函数
waitnumber节流时间(毫秒)
options{leading?: boolean; trailing?: boolean;}节流配置参数
属性说明默认值
leading是否立即执行false
trailing最后一次执行后是否再等待一段时间true

源代码&使用

ts
import { throttle } from "@manzhixing/utilsxy"

function add(a:number, b:number){
  console.log(a+b)
}

const add1 = throttle(add, 1000);

add1(1, 2)
add1(2, 3)
add1(3, 4)

// 1s 后控制台只打印一个 3

add1(4, 5)
add1(6, 7)
add1(7, 8)
add1.cancel()

// 1s 后控制台不会打印任何内容
ts
/*
 * @Author: Chengbotao
 * @Contact: https://github.com/chengbotao
 */
export function throttle(
  fn: any,
  wait: number,
  options: {
    leading?: boolean;
    trailing?: boolean;
  } = {}
) {
  let previous = 0;
  let timer: ReturnType<typeof setTimeout> | null;
  const defaultOpts = Object.assign(
    {
      leading: false,
      trailing: true,
    },
    options
  );
  const lambda = function (this: any, ...values: any[]) {
    const now = Date.now();
    const args = Array.prototype.slice.call(values);
    if (!previous && !defaultOpts.leading) previous = now;
    const remaining = wait - (now - previous);

    if (remaining <= 0 || remaining > wait) {
      if (timer) {
        clearTimeout(timer);
        timer = null;
      }

      previous = now;
      fn.apply(this, args);
      // if (!timer) args = null;
    } else if (!timer && defaultOpts.trailing) {
      timer = setTimeout(() => {
        previous = defaultOpts.leading === false ? 0 : Date.now();
        timer = null;
        const args = Array.prototype.slice.call(values);
        fn.apply(this, args);
        // if (!timer) args = null;
      }, remaining);
    }
  };

  // 取消功能
  lambda.cancel = function () {
    clearTimeout(timer as ReturnType<typeof setTimeout>);
    timer = null;
    previous = 0;
  };

  return lambda;
}