2016-04-21 34 views
6

Ich schätze lodash für seine Entprell- und Drosselfunktion sehr. Ich glaube, ich verstehe die Anwendungsfälle gut und habe sie Dutzende Male implementiert.Lodash _.debounce mit separaten Warteschlangen für eindeutige Argumentvarianten

Je nach Anforderungen kann jedoch ein erheblicher und schwer zu erfassender Fehler bei _.debounce-Funktionen mit Argumenten auftreten. Das ist das Folgende:

Angenommen, Sie haben eine Entprellfunktion namens debounceFn, die ein Argument akzeptiert und ein Entprellintervall von 1000ms hat.

  • 100ms: debounceFn(1)
  • 200ms: debounceFn(2)
  • 300ms: debounceFn(2)
  • 400ms: debounceFn(1)
  • 500ms: debounceFn(1)

Die Funktion Kind wird schließlich mit einem Argument von 1 nennen Das funktioniert hervorragend für die Größenänderung von Ereignissen, bei denen Sie sich nur für das las interessieren t-Wert, aber was ist, wenn Sie abhängig von Argumenten separate entprellte Warteschlangen benötigen? Das heißt, anstelle des Prozesses, der mit einem Argument von 1 aufgerufen wird, muss der Prozess mit Argument 1 und mit Argument 2 aufgerufen, aber nur einmal aufgerufen werden (weil beide entprellt sind).

Als ein erweitertes und etwas komplexeres Beispiel betrachten Sie eine Kombination von Argumenten unten, wo die Kombination eine eindeutige Warteschlange erzeugt.

tatsächliche Ausgabe:

  • a: lime b: kiwi

gewünschten Ausgang (Reihenfolge der ersten beiden Ausgänge könnten umgedreht werden)

  • a: apple b: banana
  • a: apple b: orange
  • a: lime b: kiwi

var process = function(a, b) { 
 
    document.writeln('a: ' + a + ' b: ' + b); 
 
}; 
 

 
var debounceProcess = _.debounce(function(a, b) { 
 
    process(a, b); 
 
}, 1000); 
 

 

 
setTimeout(function() { 
 
    debounceProcess('apple', 'orange'); 
 
}, 100); 
 
setTimeout(function() { 
 
    debounceProcess('apple', 'banana'); 
 
}, 200); 
 
setTimeout(function() { 
 
    debounceProcess('apple', 'orange'); 
 
}, 300); 
 
setTimeout(function() { 
 
    debounceProcess('lime', 'kiwi'); 
 
}, 400);
<script src="https://cdn.rawgit.com/lodash/lodash/4.6.1/dist/lodash.min.js"></script>

Ich habe viele SO Fragen auf _.debounce Annahme eines Argument gesehen. Das ist keine interessante Frage mehr. Wie erstellen Sie separate Debounce-Warteschlangen?

Was ist ein eleganter Weg (einfacher, leicht zu lesender Code), um dies mit der Lodash _.debounce-Funktion, der Lodash-Bibliothek und der nativen JavaScript-Fähigkeit zu erreichen? Vielleicht eine Kombination von _.debounce und _.memoize (Ich habe versucht, _debounce mit _.memoize zu umhüllen, aber ich muss weiter erkunden, um memoize weiter zu verstehen). Oder vielleicht eine Funktion, um die Argumente zu "hacken" und für jede Kombination von Argumenten eine neue _debounce-Queue zu erstellen?

Antwort

2

Speichern Sie die verschiedenen entprellten Funktionen in einem Objekt, wobei der Schlüssel die Argumente darstellt. Dies funktioniert in Ihrem Anwendungsfall gut, da die Argumente Strings sind.

var process = function(a, b) { 
 
    $('body').append($('<p>').text('a: ' + a + ' b: ' + b)); 
 
}; 
 

 
function debounceProcess(a, b) { 
 
    if (! debounceProcess.queues) { debounceProcess.queues = {}; } 
 
    if (! debounceProcess.queues[a]) { debounceProcess.queues[a] = {}; } 
 
    if (! debounceProcess.queues[a][b]) { 
 
    debounceProcess.queues[a][b] = _.debounce(function(a, b) { 
 
     process(a, b); 
 
    }, 1000); 
 
    } 
 
    return debounceProcess.queues[a][b](a, b); 
 
}; 
 

 
setTimeout(function() { 
 
    debounceProcess('apple', 'orange'); 
 
}, 100); 
 
setTimeout(function() { 
 
    debounceProcess('apple', 'banana'); 
 
}, 200); 
 
setTimeout(function() { 
 
    debounceProcess('apple', 'orange'); 
 
}, 300); 
 
setTimeout(function() { 
 
    debounceProcess('lime', 'kiwi'); 
 
}, 400);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://cdn.rawgit.com/lodash/lodash/4.6.1/dist/lodash.min.js"></script>

+0

Wow! Rockin '. Lass mich das ein bisschen kauen. In diesem Fall ist debounceProcess eine lokale Variable, die nicht initialisiert wurde, oder? Oder ist das eine Möglichkeit, sich an diese Funktion zu binden? – ryanm

+0

'debounceProcess' ist eine Funktion. Funktionen sind auch Objekte in Javascript, so dass Sie Eigenschaften zuweisen können. Hier habe ich die Eigenschaft 'debounceProcess.queues' zugewiesen. Ich benutze 'this' überhaupt nicht. Ich habe meine Antwort bearbeitet, um eine Funktionsdeklaration 'function debounceProcess() {...}' anstelle eines Funktionsausdrucks 'var debounceProcess = function() {...}' zu verwenden, um dies zu verdeutlichen. 'debounceProcess [a] [b]' ist auch eine Funktion, die nur einmal für jedes Paar von "a", "b" initialisiert wird. – Flimm

+0

ausgezeichnete Antwort! Gut zu wissen, wenn ich Eigenschaftszuweisungen setze, habe ich nie gedacht, das zu tun. Aus Gründen der anderen Rezensenten ist jQuery natürlich nicht erforderlich, aber ist enthalten, um ein Element anzuhängen (um es anderen zu verdeutlichen). Danke für die tolle Antwort! :) – ryanm