2016-04-21 3 views
6

Я очень благодарен lodash за его функциональные возможности отладки и дроссельной заслонки. Я считаю, что хорошо разбираюсь в случаях использования и много раз их реализовывал.Lodash _.debounce с отдельными очередями для уникальных вариантов аргументов

Однако в зависимости от требований может быть значительная и трудная ошибка с функцией _.debounce с аргументами. То есть следующее:

Предположим, что у вас есть функция debounce, называемая debounceFn, которая принимает один аргумент и имеет интервал debounce 1000 мс.

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

Функция ребенок будет в конечном счете, называющие с аргументом 1 . Это отлично работает для изменения размера событий, когда вы только заботитесь о las t, но что делать, если вам нужны отдельные очереди, зависящие от аргументов? То есть вместо процесса, вызванного с аргументом 1, нужно вызвать процесс с аргументом 1 и аргументом 2, но только один раз (потому что оба они дебютированы).

В качестве расширенного и немного более сложного примера рассмотрим комбинацию приведенных ниже аргументов, где комбинация создает уникальную очередь.

фактический выход:

  • a: lime b: kiwi

требуемый выход (порядок первых двух выходов может быть перевернута)

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

Я видел много SO вопросы о _.debounce, принимающих аргумент. Это уже не интересный вопрос, поэтому - как вы создаете отдельные очереди debounce?

Что такое элегантный способ (простой, удобный для чтения код), чтобы выполнить это с помощью функции Lodash _.debounce, библиотеки Lodash и возможности JavaScript? Возможно, сочетание _.debounce и _.memoize (я попытался обернуть _.debounce с помощью _.memoize, но вам нужно будет изучить, чтобы понять memoize дальше). Или, возможно, функция «hash» аргументов и создать новую очередь _.debounce для каждой комбинации аргументов?

ответ

2

Храните различные деблокированные функции в объекте, где ключ представляет аргументы. Это хорошо работает в вашем случае использования, потому что аргументы являются строками.

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'. Позвольте мне немного побороть это. В этом случае debounceProcess является локальной переменной, которая не была инициализирована, правильно? Или это способ связать «это» с функцией? – ryanm

+0

'debounceProcess' - это функция. Функции также являются объектами в Javascript, поэтому вы можете назначить ему свойства. Здесь я присвоил свойство 'debounceProcess.queues'. Я не использую 'this' вообще. Я отредактировал свой ответ, чтобы использовать функцию декларация 'function debounceProcess() {...}' вместо выражения функции 'var debounceProcess = function() {...}', чтобы сделать это более понятным. 'debounceProcess [a] [b]' также является функцией, которая инициализируется только один раз для каждой пары 'a',' b'. – Flimm

+0

отличный ответ! Хорошо знать, когда вы устанавливаете присвоения собственности, я никогда не думал об этом. Ради других рецензентов, jQuery, конечно, не требуется, но включен для добавления элемента (чтобы он дал понять другим, кто просматривает). Спасибо за отличный ответ! :) – ryanm