it-swarm.com.de

lodash debounce funktioniert nicht in anonymer Funktion

Hallo, ich kann nicht herausfinden, warum die Debounce-Funktion wie erwartet funktioniert, wenn sie direkt an ein Keyup-Ereignis übergeben wird. aber es funktioniert nicht, wenn ich es in eine anonyme Funktion einwickle.

Ich habe ein Problem mit dem Problem: http://jsfiddle.net/6hg95/1/

BEARBEITEN: Alles hinzugefügt, was ich versucht habe.

HTML

<input id='anonFunction'/>
<input id='noReturnAnonFunction'/>
<input id='exeDebouncedFunc'/>
<input id='function'/>
<div id='output'></div>

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

anonFunction und noReturnAnonFunction lösen die Entprellungsfunktion nicht aus; aber die letzte function feuert. Ich verstehe nicht, warum das so ist. Kann mir bitte jemand helfen, das zu verstehen?

EDIT Ok. Der Grund für das Entprellen in #exeDebouncedFunc (der von Ihnen referenzierte) ist nicht der Fall, weil die Funktion im Rahmen der anonymen Funktion ausgeführt wird und ein anderes Keyup-Ereignis ein neue Funktion in einem anderen anonymen Bereich; also die entprellte Funktion so oft abfeuern, wie Sie etwas eingeben (anstatt einmal zu feuern, was das erwartete Verhalten wäre; siehe beviour von #function)?

Können Sie bitte den Unterschied zwischen #anonFunction und #function erklären. Ist es wieder eine Frage der Frage, warum einer von ihnen arbeitet und der andere nicht?

EDIT Ok, jetzt verstehe ich, warum das so ist. Und deshalb musste ich es in eine anonyme Funktion packen:

Geige: http://jsfiddle.net/6hg95/5/

HTML

<input id='anonFunction'/>
<div id='output'></div>

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/>');
    }
})();
41

Wie Palpatim erklärt hat, liegt der Grund darin, dass _.debouce(...) eine Funktion zurückgibt, die beim Aufruf magisch ist.

Daher haben Sie in Ihrem #anonFunction-Beispiel einen Schlüssellistener, der beim Aufruf nur eine Funktion an den Aufrufer zurückgibt, die mit den Rückgabewerten des Ereignislisteners nichts tut.

Dies ist ein Ausschnitt aus der Definition von _.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);
    };
  } 

Ihr Schlüsselereignislistener muss die zurückgegebene Funktion von _.debounce(...) aufrufen, oder Sie können dies wie in Ihrem nicht anonymen Beispiel tun und die zurückgegebene Funktion des _.debounce(...)-Aufrufs als Ereignislistener verwenden.

46
Michael Dahl

debounce führt die Funktion nicht aus, es gibt eine Funktion mit der eingebauten Debounciness zurück.

Kehrt zurück

(Funktion): Gibt die neue entprellte Funktion zurück.

Ihr #function-Handler führt also das Richtige aus, indem er eine Funktion zurückgibt, die von jQuery als Keyup-Handler verwendet wird. Um Ihr #noReturnAnonFunction-Beispiel zu korrigieren, können Sie die entprägte Funktion einfach im Kontext Ihrer Funktion ausführen:

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

Das bedeutet jedoch, dass ein unnötiger anonymer Funktions-Wrapper für Ihr Debounce eingeführt wird.

34
Palpatim

Denken Sie leichter

_.debounce liefert eine entprägte Funktion zurück!

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

sie rufen stattdessen die entprellte Funktion auf

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

$el.on('keyup', doYourThingDebounced);
22
zevero

Sie können die Entprellungsfunktion folgendermaßen zurückgeben:

(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/>');
    }
})();
6
jiv-e

Wenn Sie ein Debounce mit nachlaufendem Verhalten (Konten für den letzten Klick oder wahrscheinlichere letzte Änderung an einer Auswahleingabe) und ein visuelles Feedback zum ersten Klick/zu einer Änderung wünschen, haben Sie generell das gleiche Problem.

Das funktioniert nicht:

$(document).on('change', "#select", function() {
    $('.ajax-loader').show();
    _.debounce(processSelectChange, 1000);
});

Dies wäre eine Lösung:

$(document).on('change', "#select", function() {
    $('.ajax-loader').show();
});
$(document).on('change', "#select", _.debounce(processSelectChange, 1000));
0
Baishu