在Javascript中缓存取消公告的函数

在Javascript中缓存取消公告的函数,javascript,functional-programming,lodash,memoization,debouncing,Javascript,Functional Programming,Lodash,Memoization,Debouncing,我正在尝试创建一个函数包装器,它可以用一个DOM元素作为参数调用,并将返回一个唯一的非公告函数,该函数绑定到该DOM元素,其中包含一些逻辑 我将逐步阐明我的思维过程: 这是原始的去模糊函数 现在,这个函数工作得非常好,直到我意识到我将去Bounced函数绑定到调用它的第一个元素。所以,如果我想创造: hideElementWhenIdle( $("selector-1") ); hideElementWhenIdle( $("selector-2") );

我正在尝试创建一个函数包装器,它可以用一个DOM元素作为参数调用,并将返回一个唯一的非公告函数,该函数绑定到该DOM元素,其中包含一些逻辑

我将逐步阐明我的思维过程:

这是原始的去模糊函数 现在,这个函数工作得非常好,直到我意识到我将去Bounced函数绑定到调用它的第一个元素。所以,如果我想创造:

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") );
现在我可以调用两个独立的函数。然而,这显然是肮脏和不可伸缩的(不过,公平地说,我只有两个元素需要应用于函数)

失败的尝试 我想我可以
包装
记忆
我的函数来实现我想做的事情,但是在尝试了几次之后,我无法理解正在发生的事情(或者它是否是正确的解决方案)。以下是我的最新尝试:

var hideElementWhenIdle = _.wrap(
  _.memoize( 
    function($el) {
      var fn = _.debounce(() => {
        // ... same as above
      }
    ),
  function(func, $el) {
    return func($el);
  }
);
我猜我这里的问题是,
总是返回相同的值,所以我总是缓存相同的值,而不管
$el

我认为你的肮脏解决方案是正确的。或者你需要你自己的去Bouncer:

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节点可以工作


在我看来,脏的解决方案非常干净和坚固……嗯……谢谢你的回复。脏解决方案的问题是,随着我不断添加元素,它完全无法扩展。我没有试过你的去弹片功能,但看起来它可能会奏效。尽管我不想再次编写整个
debounce
,因为我使用的是lodash实现。我认为地图的设置正是
memoize
所做的,这就是为什么我要走这条路。对此有什么建议吗?为什么不起作用?也许出于与您所说的相同的原因,我应该传递DOM节点?@sunyatasattva您需要两者的混合,而5行程序可能比lodash更轻
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