Answer

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

Report Page