【问题标题】:Caching debounced functions in Javascript在 Javascript 中缓存去抖动的函数
【发布时间】:2017-12-29 03:36:51
【问题描述】:

我正在尝试创建一个函数包装器,它可以使用 DOM 元素作为参数进行调用,并将返回一个与该 DOM 元素相关联的唯一去抖动函数,其中包含一些逻辑。

我会逐步阐明我的思考过程:

这是原来的去抖函数

hideElementWhenIdle = _.debounce(($el) => {
  if($el.is(":hover"))
    hideElementWhenIdle($el);
  else
    $el.removeClass("visible");
}, 5000);

现在,这个函数工作得非常好,直到我意识到我将去抖函数绑定到它被调用的第一个元素。所以,如果我想创建:

hideElementWhenIdle( $("selector-1") );
hideElementWhenIdle( $("selector-2") );

它们基本上会相互消除抖动。我想要的是每个元素都有独特的功能。

脏溶液

我当然可以这样做:

hideElementWhenIdle = function($el) {
  let fn = _.debounce(($el) => {
    // ... same as above
  }, 5000);
  
  return fn;
}

hideSelector1WhenIdle = hideElementWhenIdle( $("selector-1") );
hideSelector2WhenIdle = hideElementWhenIdle( $("selector-2") );

现在我将拥有两个可以调用的独立函数。然而,这显然是肮脏且不可扩展的(不过,公平地说,我只有两个元素需要应用到函数上)。

尝试失败

我以为我可以 wrapmemoize 我的功能来实现我想做的事情,但是在尝试了几次之后,我无法理解正在发生的事情(或者如果它甚至是正确的解决方案) .这是我最近的尝试:

var hideElementWhenIdle = _.wrap(
  _.memoize( 
    function($el) {
      var fn = _.debounce(() => {
        // ... same as above
      }
    ),
  function(func, $el) {
    return func($el);
  }
);

我猜我的问题是 _.debounce 总是返回相同的值,所以无论$el 如何,我总是缓存相同的值。

【问题讨论】:

  • dirty 解决方案在我看来是相当干净和健壮的......

标签: javascript functional-programming lodash memoization debouncing


【解决方案1】:

您的 dirty 解决方案是我认为的解决方案。或者您需要自己的去抖动器:

function debounce(func,time){
   var debouncing=new Map();
   return function(el){
        if(!debouncing.get(el)){
            debouncing.set(el,setTimeout(_=>debouncing.set(el,null),time));
            return func(el);
        }
    };
}

用例:

var func=debounce(function(el){
   $el=$(el);
   if($el.is(":hover"))
      hideElementWhenIdle($el);
   else
     $el.removeClass("visible");
 }, 5000);

func("#sth");
func("#sth");//debounced
func("#sthelse");//not debounced

注意:这不适用于传递 jquery 对象,因为它们是唯一的。 DOM 节点可以工作。

http://jsbin.com/bujocoravu/1/edit?js

【讨论】:

  • 嗯……谢谢你的回复。肮脏的解决方案的问题在于,随着我不断添加元素,它完全无法扩展。我没有尝试您的去抖动功能,但看起来它可能会奏效。虽然我不想再写整个debounce,因为我使用的是lodash实现。我认为地图的设置正是memoize 所做的,这就是我试图走这条路的原因。对此有何建议以及为什么它不起作用?也许和你说的原因一样,我应该传递 DOM 节点?
  • @sunyatasattva 你需要两者的混合,并且 5 班轮可能比 lodash 更轻量
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-16
  • 2014-10-26
  • 2018-10-01
  • 1970-01-01
  • 2017-04-27
  • 2023-02-02
相关资源
最近更新 更多