lodash debounce不能在匿名函数中工作

Kri*_*ett 52 javascript jquery lodash

您好我无法弄清楚为什么当直接传递给keyup事件时debounce函数按预期工作; 但如果我将它包装在匿名函数中,它就不起作用.

我有问题:http : //jsfiddle.net/6hg95/1/

编辑:添加了我尝试过的所有东西.

HTML

<input id='anonFunction'/>
<input id='noReturnAnonFunction'/>
<input id='exeDebouncedFunc'/>
<input id='function'/>
<div id='output'></div>
Run Code Online (Sandbox Code Playgroud)

JAVASCRIPT

$(document).ready(function(){
    $('#anonFunction').on('keyup', function () {
        return _.debounce(debounceIt, 500, false); //Why does this differ from #function
    });
    $('#noReturnAnonFunction').on('keyup', function () {
        _.debounce(debounceIt, 500, false); //Not being executed
    });
    $('#exeDebouncedFunc').on('keyup', function () {
        _.debounce(debounceIt, 500, false)(); //Executing the debounced function results in wrong behaviour
    });
    $('#function').on('keyup', _.debounce(debounceIt, 500, false)); //This is working.
});

function debounceIt(){
    $('#output').append('debounced');
}
Run Code Online (Sandbox Code Playgroud)

anonFunction并且noReturnAnonFunction不会启动去抖功能; 但是最后一次function起火了.我不明白为什么会这样.任何人都可以帮我理解这个吗?

编辑 好了,所以在#exeDebouncedFunc(你引用的那个)中没有发生去抖的原因是因为该函数在匿名函数的范围内执行而另一个keyup事件将在另一个匿名范围内创建一个新函数; 因此,当您键入内容时,多次触发去抖动函数(而不是一次性触发,这将是预期的行为;请参阅beviour #function)?

能否请您解释之间的差异#anonFunction#function.这又是一个范围问题,为什么其中一个有效,另一个无效?

编辑 好的,现在我明白为什么会这样.这就是我需要将其包装在匿名函数中的原因:

小提琴:http://jsfiddle.net/6hg95/5/

HTML

<input id='anonFunction'/>
<div id='output'></div>
Run Code Online (Sandbox Code Playgroud)

JAVASCRIPT

(function(){
    var debounce = _.debounce(fireServerEvent, 500, false);

    $('#anonFunction').on('keyup', function () {
        //clear textfield
        $('#output').append('clearNotifications<br/>');
        debounce();
    });

    function fireServerEvent(){
        $('#output').append('serverEvent<br/>');
    }
})();
Run Code Online (Sandbox Code Playgroud)

小智 53

正如Palpatim所解释的那样,原因在于_.debouce(...)返回一个函数,该函数在被调用时具有魔力.

因此,在您的#anonFunction示例中,您有一个键侦听器,在调用时只会向调用者返回一个函数,该函数不会对事件侦听器的返回值执行任何操作.

这是_.debounce(...)定义的片段:

_.debounce
function (func, wait, immediate) {
    var timeout;
    return function() {
      var context = this, args = arguments;
      var later = function() {
        timeout = null;
        if (!immediate) func.apply(context, args);
      };
      if (immediate && !timeout) func.apply(context, args);
      clearTimeout(timeout);
      timeout = setTimeout(later, wait);
    };
  } 
Run Code Online (Sandbox Code Playgroud)

您的键事件侦听器必须从_.debounce(...)您的非匿名示例中_.debounce(...)调用返回的函数,并且可以将调用中返回的函数用作事件侦听器.

  • +1进行解释。基本上是这样的:$('#function')。on('keyup',_.debounce(debounceIt,500,false)); //这正在工作。`是为什么去抖动返回函数。像这样美丽,而Just Makes Sense™ (2认同)

Pal*_*tim 41

debounce 不执行该函数,它返回一个内置了debounciness的函数.

返回

(功能):返回新的去抖动功能.

所以你的#function处理程序实际上正在做正确的事情,通过返回一个由jQuery用作keyup处理程序的函数.要修复您的#noReturnAnonFunction示例,您只需在函数的上下文中执行去抖动函数:

$('#noReturnAnonFunction').on('keyup', function () {
    _.debounce(debounceIt, 500, false)(); // Immediately executes
});
Run Code Online (Sandbox Code Playgroud)

但是这会引入一个不必要的匿名函数包装你的debounce.

  • 这么多投票,但是恕我直言,这行不通。每次按键时,函数debounceIt都会被转换为一个去抖动的函数并立即执行,其效果是debounceIt将被延迟500ms。每次按键都会重复一次!因此,最后,您的代码等效于$('#noReturnAnonFunction')。on('keyup',function(){setTimeout(debounceIt,500);})没有反跳...只是延迟。 (4认同)
  • 你是对的。我不认为这是消抖。正在拖延时间 (2认同)

zev*_*ero 35

想想更容易

_.debounce返回去抖功能!所以不要考虑

$el.on('keyup'), function(){
   _.debounce(doYourThing,500); //uh I want to debounce this
}
Run Code Online (Sandbox Code Playgroud)

你宁愿调用debounced函数

var doYourThingDebounced = _.debounce(doYourThing, 500); //YES, this will always be debounced

$el.on('keyup', doYourThingDebounced);
Run Code Online (Sandbox Code Playgroud)

  • 如果我必须在“keyup”上调用多个函数并且只应该对其中一个函数进行反跳怎么办? (2认同)

jiv*_*v-e 6

您可以像这样返回去抖功能:

(function(){
    var debounce = _.debounce(fireServerEvent, 500, false);

    $('#anonFunction').on('keyup', function () {
        //clear textfield
        $('#output').append('clearNotifications<br/>');
        return debounce();
    });

    function fireServerEvent(){
        $('#output').append('serverEvent<br/>');
    }
})();
Run Code Online (Sandbox Code Playgroud)