速率限制和.apply方法与.throttle

Rate limiting an .apply method with _.throttle

本文关键字:方法 throttle apply 速率      更新时间:2023-09-26

是否有可能限制速率,节流或解密像this[act].apply(this, data)这样的东西?下划线还是别的什么?我试过很多东西,比如

_.throttle(/* different permutations of combined args */)

_.throttle.apply(/* same */)

_.throttle.apply(myArgs)(throttleArgs)

_.throttle(throttleArgs).apply(myArgs)

等。有些产生错误,有些冻结执行,有些调用apply方法(正确的范围和参数,但没有限制)。什么好主意吗?使用CoffeeScript,这些是类方法

由于您正在调用的原始函数

this[act].apply(this, data)

使用this,我假设你是从对象的方法中调用它。问题是,如何让this从这里到那里?许多高阶函数被设计成使用与调用它们自身相同的this来调用底层函数,使用以下类型的框架:

function higher_order_function(fn) {
  return function() {
    return fn.apply(this, arguments);
  };
}

这意味着,如果我有一个方法

的对象
var obj = {
  val: 42,
  print: function() { console.log(this.val); }
}

然后我要变换print函数:

obj.newPrint = higher_order_function(obj.print);

我现在可以调用obj.newPrint,下面,this将被用来调用print,一切工作如预期。

对于这样的事情,有其他的设计,包括显式地传递上下文(this),并将它们作为单独的参数给函数,但上面的方法通常更干净,而且"刚刚好"。

这就是_.throttle的工作原理。如果你看一下源代码,你会看到它做了像

这样的事情
return function() {
  ...
  context = this;
  args = arguments;
  ...
  result = func.apply(context, args);
};

这意味着,要以节流方式调用代码,您需要做的就是安排使用this调用它。

让我们假设你调用的原始代码是在一个名为act的函数中。

var obj = {
  act: function(act) {
    this[act].apply(this, data);
  }
};

要制作act的节流版本(这里,我们直接在对象上制作它;您可以通过将其放在原型上实现类似的功能,见下文):

obj.throttledAct = _.throttle(obj.act);

然后调用

obj.throttledAct('act1')

如果你正在使用原型编程:

Foo.prototype.func = function(act) { this[act].apply(this, data) };

然后你可以把节流版本放在原型上:

Foo.prototype.throttledFunc = _.throttle(Foo.prototype.func);

,一切都会如你所愿。

如果出于某种原因,您想要创建一个独立版本的throttated函数,而不将其放在对象或原型中:

var throttledFunc = _.throttled(func);

你可以用callapply调用它来强制this的值:

throttledFunc.call(obj, 'act1`);

但是在这两种情况下,参数'act1'是如何传递给底层函数的。这也可以通过_.throttle实现中读取

的那一行来完成
result = func.apply(context, args);

这里args是传递给由_.throttle构造的函数的参数,apply用于将它们和this一起传递给底层函数。注意,_.throttle本身也需要额外的参数传递给底层函数,但这是"烧掉它们",而不是让它们在每次调用throttated函数时指定。

你尝试
_.throttle(/* different permutations of combined args */)
_.throttle.apply(/* same */)
_.throttle.apply(myArgs)(throttleArgs)
_.throttle(throttleArgs).apply(myArgs)

所有这些都有同样的问题,即_.throttle必须传递一个函数进行节流,并返回一个函数,然后调用该函数以获得节流行为。最后一个可能是最接近的,假设throttleArgs是要节流的函数,而myArgs实际上是this, myArgs