Регулирование функций Javascript

Я хочу использовать JS Throttle. Но я изо всех сил пытаюсь заставить его работать правильно.

Я попробовал код из этой статьи: https://codeburst.io/throttling-and-debouncing-in-javascript-b01cad5c8edf

Но дроссельная заслонка не работает должным образом, так как каждый раз, когда я нажимаю на кнопку, один "|" добавляется в div. Ни один клик не был сброшен.

where is the misstake?

function foo() {
	$("#respond").append("|");
}

const throttle = (func, limit) => {
  let inThrottle
  return function() {
    const args = arguments
    const context = this
    if (!inThrottle) {
      func.apply(context, args)
      inThrottle = true
      setTimeout(() => inThrottle = false, limit)
    }
  }
}

var onClick = function() {
    throttle(foo(), 50000);
};

$('#button').click(onClick);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" id="button" value="Click Me" />
<div id="respond"></div>


person CL90    schedule 18.10.2018    source источник
comment
foo() -> foo в противном случае вы выполняете функцию немедленно вместо того, чтобы указывать ссылку на функцию для выполнения позже.   -  person VLAZ    schedule 18.10.2018
comment
Вы также, кажется, возвращаете функцию из throttle, но никогда не выполняете ее. Глядя на код, кажется, что вы действительно хотите сделать $('#button').click(throttle(foo, 50000));, поэтому вы делаете возвращаемую функцию обработчиком.   -  person VLAZ    schedule 18.10.2018
comment
Ах, спасибо! Но почему это: $('#button').click(throttle(foo, 50000)); работает, а "var onClick = function() { throttle(foo, 50000); }; $('#button').click(onClick);" нет?   -  person CL90    schedule 18.10.2018
comment
Потому что throttle(foo, 50000) по-прежнему возвращает ссылку на функцию, которую нужно выполнить позже. По сути, происходит то, что ваш обработчик выполняет var functionReference = throttle(foo, 50000), а затем ничего не делает вместо вызова functionReference(). Наличие функции, которая просто вызывает другую функцию без аргументов (помните, что функция, которую вы получаете, не принимает никаких аргументов, поэтому вы как бы получаете немного запаха кода giveCallback(() => otherFunc()) проще выразить как giveCallback(otherFunc), поэтому я предложил прямо дать это functionReference в качестве обработчика.   -  person VLAZ    schedule 18.10.2018


Ответы (3)


Чтобы throttle(func, limit) работал, может быть только один экземпляр его продукта.

Проблема в том, что функция onClick в вашем примере создает новый экземпляр при каждом вызове.

Это делает базовую переменную inThrottle бессмысленной, поскольку для каждого клика создается новая копия.

Решение состоит в том, чтобы напрямую вызвать один единственный экземпляр продукта throttle(foo, 50000).

Также должен передаваться сам foo (а не его продукт).

См. ниже практический пример, а также замыкания и область для получения дополнительной информации.

// Foo.
const foo = (...args) => {
  $("#respond").append("|");
}

// Throttle.
const throttle = (func, limit) => {
  let inThrottle
  return (...args) => {
    if (!inThrottle) {
      func(...args)
      inThrottle = setTimeout(() => inThrottle = false, limit)
    }
  }
}

// On Click.
const onClick = throttle(foo, 1000)

// Button - Click.
$('#button').click(onClick);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" id="button" value="Click Me" />
<div id="respond"></div>

person Arman Charan    schedule 18.10.2018

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

var onClick = function() {
    throttle(foo(), 50000);
};
// TO

var onClick = throttle(foo, 50000);
person Austio    schedule 18.10.2018

Я знаю, что вопрос старый.

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

function throttle( fn, wait ){
  let lastCall = 0;
    return function(){
    if( Date.now() - lastCall > wait  ){
      lastCall = Date.now()
      fn()
    }
  }
}

var counter = 0

var count = () => document.querySelector("#count").textContent = ++counter

window.addEventListener('scroll', throttle( count, 1000 ) )
body{
  height: 2000px;
}
<h1 id='count'>
  0
</h1>

person albseb    schedule 11.07.2020