ZdraviiSmisl
@ZdraviiSmisl

Для чего контекст и аргументы приравнивают к null?

Напишите функцию throttle(f, ms) – «тормозилку», которая возвращает обёртку, передающую вызов f не чаще, чем раз в ms миллисекунд

Визуально это даст следующую картину обработки перемещений мыши:

1.Первое обновление произойдёт сразу (это важно, посетитель тут же видит реакцию на своё действие).

2.Дальше может быть много вызовов (микро-передвижений) с разными координатами, но пока не пройдёт 100 мс – ничего не будет.

3.По истечении 100 мс – опять обновление, с последними координатами. Промежуточные микро-передвижения игнорированы.

4.В конце концов мышь где-то остановится, обновление по окончании очередной паузы 100 мс сработает с последними координатами.

function throttle(func, ms) {

var isThrottled = false,
savedArgs,
savedThis;

function wrapper() {

if (isThrottled) { // (2)
savedArgs = arguments;
savedThis = this;
return;
}

func.apply(this, arguments); // (1)

isThrottled = true;

setTimeout(function() {
isThrottled = false; // (3)
if (savedArgs) {
wrapper.apply(savedThis, savedArgs);
savedArgs = savedThis = null;
}
}, ms);
}

return wrapper;
}
Шаги работы этой функции:

1.Декоратор throttle возвращает функцию-обёртку wrapper, которая при первом вызове запускает func и переходит в состояние «паузы» (isThrottled = true).

2.В этом состоянии все новые вызовы запоминаются в замыкании через savedArgs/savedThis. Обратим внимание, что и контекст вызова и аргументы для нас одинаково важны и запоминаются одновременно. Только зная и то и другое, можно воспроизвести вызов правильно.

3.Далее, когда пройдёт таймаут ms миллисекунд – пауза будет снята, а wrapper – запущен с последними аргументами и контекстом (если во время паузы были вызовы).

Шаг (3) запускает именно не саму функцию, а снова wrapper, так как необходимо не только выполнить func, но и снова поставить выполнение на паузу. Получается последовательность «вызов – пауза… вызов – пауза … вызов – пауза …», каждое выполнение в обязательном порядке сопровождается паузой после него. Это удобно описывается рекурсией.

У меня вопрос по строке savedArgs = savedThis = null. В данном случае контекст и аргументы становятся пустыми,потому что был последний вызов и он сработал с последними аргументами. И что бы вновь поставить func на паузу, по сути приравнивают аргументы и контеiкст к null?
  • Вопрос задан
  • 114 просмотров
Решения вопроса 1
IceRD
@IceRD
setTimeout(function() {
isThrottled = false; // (3)
if (savedArgs) {
wrapper.apply(savedThis, savedArgs);
savedArgs = savedThis = null;
}
}, ms);
}

запускается цикл выполняющийся каждые N ms
Это не совсем пауза, если savedArgs и savedThis не убивать, в таком случае будет постоянно выполнятся последнее через действие N ms , даже если других изменений не произошло.

Простыми словами, если картинка статическая и на ней ничего не происходит, нет необходимости каждые 100мс выполнять процесс и менять одну и туже информацию (менять на то, что и так уже есть).
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы