Answer
t.me/js_testОтвет:
function throttle(func, ms) {
let isThrottled = false,
savedArgs,
savedThis;
function wrapper() {
if (isThrottled) {
savedArgs = arguments;
savedThis = this;
return;
}
func.apply(this, arguments);
isThrottled = true;
setTimeout(() => {
isThrottled = false;
if (savedArgs) {
wrapper.apply(savedThis, savedArgs);
savedArgs = savedThis = null;
}
}, ms);
}
return wrapper;
}
Объяснение:
Создаём три переменные isThrottled - флаг для отслеживания состояния, savedArgs - переменная для хранения аргументов и savedThis - переменная для хранения контекста. Затем создаём функцию wrapper которую в последствии вернём. Внутри этой функции, если флаг isThrottled равен true, то просто сохраняем аргументы и контекст, если же он равен false, то вызываем переданную функцию, ставим isThrottled в true и заводим таймер на количество миллисекунд ms, который и является основой данной функции. Внутри коллбэка в таймере: ставим isThrottled в false, для того чтобы дать возможность выполнять переданную функцию и если у нас есть сохранённые аргументы то вызываем wrapper и сбрасываем их.
Код для проверки:
function throttle(func, ms) {
let isThrottled = false,
savedArgs,
savedThis;
function wrapper() {
if (isThrottled) {
savedArgs = arguments;
savedThis = this;
return;
}
func.apply(this, arguments);
isThrottled = true;
setTimeout(() => {
isThrottled = false;
if (savedArgs) {
wrapper.apply(savedThis, savedArgs);
savedArgs = savedThis = null;
}
}, ms);
}
return wrapper;
}
let f1000 = throttle(console.log, 1000);
f1000(1); // 1
f1000(2); // nothing
f1000(3); // 3