JavaScript 中的节流函数

Jagathish 2023年10月12日
JavaScript 中的节流函数

本教程介绍如何在 JavaScript 中为函数添加节流函数。

在 JavaScript 中添加节流限制

我们可以通过限流来限制某个资源在特定时限内被访问的次数。

例如,我们将一个函数配置为在一分钟内仅调用 10 次。当我们调用超过 10 次时,应该阻止执行。

为了实现节流,我们将维护以下数据:

  • 保持函数被调用的最大次数的变量。
  • 保持时间范围的变量(如 1 分钟)。
  • 用于维护上次调用该方法的时间的变量。
  • 用于维护在当前时间范围内调用函数的次数的变量。

JavaScript 中的节流算法

调用该函数时,我们将按照以下步骤进行操作:

  • 查找当前时间与上次调用函数的时间之间的时间差。
    timeDiff = currentTime - lastInvokedTime
    
  • 如果时间差大于配置的 timeFrame,将函数在当前时间帧内调用的次数重置为 0
    if (timeDiff >= timeFrame) {
      numberOfTimesInvoked = 0;
    }
    
  • 检查函数在当前时间范围内被调用的次数是否小于或等于配置的函数可以被调用的次数。
    if (numberOfTimesInvoked < numOfTimesFnCanBeInvoked) {
      // invoke the function
    } else {
      // log fn cannot be invoked more than n times
    }
    
  • 在调用函数时,我们应该将函数调用的次数增加 1。此外,最后调用的时间应更新为当前时间。

代码示例:

class Throttle {
  constructor(timeFrame, numOfTimesFnCanBeInvoked, func) {
    this.lastInvokedTime = 0;
    this.numberOfTimesInvoked = 0;
    this.timeFrame = timeFrame;
    this.numOfTimesFnCanBeInvoked = numOfTimesFnCanBeInvoked;
    this.func = func;
  }
  call() {
    let currentTime = new Date();
    let timeDiff = currentTime - this.lastInvokedTime;
    if (timeDiff >= this.timeFrame) {
      this.numberOfTimesInvoked = 0;
    }
    if (this.numberOfTimesInvoked < this.numOfTimesFnCanBeInvoked) {
      this.func.apply(this, arguments);
      this.numberOfTimesInvoked++;
      this.lastInvokedTime = currentTime;
    } else {
      console.log(`Trying to call more than ${
          this.numOfTimesFnCanBeInvoked} times within ${this.timeFrame}ms`);
    }
  }
}

上面的代码将处理函数的限制。让我们创建一个函数并为此添加限制。

function add(a,b){
  console.log(`${a} + ${b} = ${a+b}`);
}

let sum = new Throttle(2000, 2, add) // in 10 sec only two time this method can be called

sum.call(1,2);
sum.call(3,4);
sum.call(5,6); // this will not be executed

setTimeout(()=>{
	console.log("After 2000ms");
	sum.call(5,6); // this will be executed 
	sum.call(7,8);
}, 2000);

输出

1 + 2 = 3
3 + 4 = 7
Trying to call more than 2 times within 2000ms

After 2000ms
5 + 6 = 11
7 + 8 = 15

在上面的代码中,

  • 我们创建了一个函数 add
  • 我们为 Throttle 类创建了一个新对象。将 add 函数配置为在 2 秒内仅调用两次。
  • 我们在 2 秒内调用了 add 函数 3 次。对于前两个函数调用,函数将被执行。但是对于第三次函数调用,该函数将不会被调用。
  • 我们使用 setTimeout 在 2 秒后调用 add 函数。这个时间段将是新的,这样函数就会被执行。

相关文章 - JavaScript Function