2016-04-21 5 views
6

Apprezzo molto lodash per la sua funzionalità di antirimbalzo e acceleratore. Credo di aver capito bene i casi d'uso e li ho implementati decine di volte.Lodash _.debounce con code separate per varianti di argomenti univoci

Tuttavia, in base ai requisiti, è possibile che vi sia un errore significativo e difficile da rilevare con le funzioni _.debounce con argomenti. Questo è il seguente:

Si supponga di disporre di una funzione di antirimbalzo chiamata debounceFn che accetta un argomento e ha un intervallo di rimbalzo di 1000 ms.

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

La funzione bambino finirà per chiamare con un argomento di 1 Questo funziona benissimo per ridimensionare gli eventi in cui ti interessa solo le las t valore, ma cosa succede se hai bisogno di code separate per il rimbalzo a seconda degli argomenti? Cioè, invece del processo chiamato con un argomento di 1, si ha il processo chiamato con argomento 1 e con argomento 2, ma chiamato solo una volta (perché entrambi sono rimossi).

Come esempio esteso e leggermente più complesso, prendere in considerazione una combinazione di argomenti di seguito, in cui la combinazione produce una coda univoca.

uscita effettiva:

  • a: lime b: kiwi

uscita desiderato (ordine delle prime due uscite potrebbe essere capovolto)

  • 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>

ho visto molte domande sul SO _.debounce accettare un argomento. Questa non è più una domanda interessante, quindi - come si creano code di debounce separate?

Che cosa è un modo elegante (codice semplice e di facile lettura) per ottenere ciò utilizzando la funzione Lodash _.debounce, la libreria Lodash e la capacità nativa di JavaScript? Forse una combinazione di _.debounce e _.memoize (ho provato a racchiudere _.debounce con _.memoize ma dovrò esplorare per capire meglio il memoize). O forse una funzione per "cancellare" gli argomenti e creare una nuova coda _.debounce per ciascuna combinazione di argomenti?

risposta

2

Memorizza le diverse funzioni di rimbalzo in un oggetto, in cui la chiave rappresenta gli argomenti. Questo funziona bene nel tuo caso d'uso, perché gli argomenti sono stringhe.

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'. Lascia che lo mastichi un po '. In questo caso, debounceProcess è una variabile locale che non è stata inizializzata, giusto? O è un modo per legare "questo" alla funzione? – ryanm

+0

'debounceProcess' è una funzione. Le funzioni sono anche oggetti in Javascript, quindi puoi assegnarle delle proprietà. Qui ho assegnato la proprietà 'debounceProcess.queues'. Non sto usando "questo" affatto. Ho modificato la mia risposta per usare una funzione di dichiarazione 'function debounceProcess() {...}' invece di un'espressione di funzione 'var debounceProcess = function() {...}' per rendere più chiaro questo. 'debounceProcess [a] [b]' è anche una funzione, che viene inizializzata solo una volta per ogni coppia di 'a',' b'. – Flimm

+0

risposta eccellente! Buono a sapersi su come impostare gli incarichi di proprietà, non ho mai pensato di farlo. Per il bene degli altri recensori, jQuery ovviamente non è necessario ma è incluso per aggiungere un elemento (per renderlo chiaro agli altri che lo esaminano). Grazie per l'ottima risposta! :) – ryanm