使用_.throttle对.apply方法进行速率限制

时间:2015-08-29 21:49:45

标签: javascript function methods underscore.js throttling

是否可以对this[act].apply(this, data)之类的内容进行限速,限制或去抖?用下划线或别的东西?我尝试了很多东西,比如

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

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

_.throttle.apply(myArgs)(throttleArgs)

_.throttle(throttleArgs).apply(myArgs)

等。一些产生错误,一些冻结执行,一些调用apply方法(正确的范围和args但没有限制)。有任何想法吗?使用CoffeeScript,这些是类方法。

1 个答案:

答案 0 :(得分:2)

由于您正在调用原始函数

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)并将它们作为函数的单独参数给出,但上面的方法通常更清晰,而且#34;只是工作"。

这就是_.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);

一切都会按预期工作。

如果由于某种原因你想创建一个独立版本的限制函数,而不是把它放在一个对象或原型中:

var throttledFunc = _.throttled(func);

然后,您可以使用callapply调用它来强制this的值:

throttledFunc.call(obj, 'act1`);

但在任何一种情况下,参数'act1'如何传递给底层函数。这也是通过执行_.throttle读取

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

此处args是传递给由_.throttle构造的函数的参数,apply用于将它们与this一起传递给基础函数。请注意,_.throttle本身也会将其他参数传递给基础函数,但是"将它们烧录在"而不是每次调用限制函数时都指定它们。

您的尝试

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

所有这些都遇到了同样的问题,即_.throttle必须传递一个函数才能被限制,并返回一个函数,然后调用该函数来获取受限制的行为。假设throttleArgs是要受限制的函数,最后一个可能是最接近的,myArgs实际上是this, myArgs