【问题标题】:Rate limiting an .apply method with _.throttle使用 _.throttle 限制 .apply 方法的速率
【发布时间】:2015-11-24 07:02:08
【问题描述】:

是否可以对this[act].apply(this, data) 之类的东西进行速率限制、节流或去抖动?用下划线还是别的什么?我已经尝试了很多东西,比如

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

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

_.throttle.apply(myArgs)(throttleArgs)

_.throttle(throttleArgs).apply(myArgs)

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

【问题讨论】:

    标签: javascript function methods underscore.js throttling


    【解决方案1】:

    因为你调用的原始函数

    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);
    

    一切都会按预期进行。

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

    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

    【讨论】:

    • 感谢您的详尽回答!在某些事情中,所以我正在等待接受它,直到我回来解决这个问题。对于上下文,我使用的是 CoffeeScript,这些是类方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-17
    • 2016-02-22
    • 1970-01-01
    • 1970-01-01
    • 2017-10-03
    相关资源
    最近更新 更多