Снимка на Крис Liverani на Unsplash

Debounce срещу Throttle срещу изпълнение на опашката

В интернет имаме множество статии, които обясняват какво са Debouncing, Throttling и каква е разликата между тях. Но повечето, които намерих, често бяха дълги, объркващи и със сложни примери за код (ако има такива).

Така че аз измислих опростени примери за работещ код, за да получат концепцията в един миг. Да започнем с по-лесния, Debounce.

Debounce

Дебансирането на функция е полезно, когато се извиква непрекъснато и искаме тя да се изпълни след определен период, ако времето е минало от последното повикване.

Това е полезно в случаите, когато искаме ситуацията да се стабилизира, преди да се обадим на обработващия, за да подобрим производителността. Един от най-добрите примери за разгонване, който намерих, беше в този блог от Джей Томпкинс

За разделяне може да имаме функция за автоматично запазване в нашето приложение. С автоматично запазване на приложението се опитва да запази състоянието на нашето приложение всеки път, когато потребителят направи актуализация или има някакво взаимодействие. Изчаква се 5 секунди, за да се увери, че не се правят други актуализации или взаимодействия, преди да се запази състоянието, в което тя записва новото състояние, и да повтори процеса. Ако се случи някакво взаимодействие, той нулира таймера си отново за 5 секунди.

функция разобръщане (func, waitTime) {
    var timeout;

    функция за връщане () {
        clearTimeout (таймаут);
        timeout = setTimeout (func, waitTime);
    };
};

Това е, това колко просто може да бъде дебютирането.

Дросел

Тази техника е по-подходящо наречена. Дроселирането на функция е полезно, когато се извиква непрекъснато и искаме тя да се изпълнява веднъж на всеки x секунди. Добър пример за това би бил манипулаторът на превъртане или манипулатора на оразмеряване, където искаме да изпълним манипулатора веднъж за определен период от време, дори ако функцията се извиква непрекъснато.

функция дросел (func, waitTime) {
    var timeout = null;
    var предходен = 0;

    var later = function () {
        предишен = Date.now ();
        timeout = нула;
        функция ();
    };

    функция за връщане () {
        var now = Date.now ();
        var preostali = waitTime - (сега - предишен);
        ако (остава <= 0 || оставащо> време на изчакване) {
            ако (изчакване) {
                clearTimeout (таймаут);
            }
            по късно();
        } else if (! timeout) {// null timeout -> няма чакащо изпълнение
            
            timeout = setTimeout (по-късно, оставащо);
        }
    };
};

Допълнително: опашка

По линиите на разобличаване и дроселиране, функционалните обаждания също могат да бъдат поставени на опашка. При това функцията се изпълнява броя пъти, когато е извикана, но има фиксирано време на чакане преди всяко изпълнение. Това беше полезно наскоро за мен, когато използвах библиотека и попаднах на грешка, извикваща функция в нея няколко пъти, без забавяне причиняваше проблем. (може да има и други случаи на употреба :))

опашка за функция (func, waitTime) {
    var funcQueue = [];
    вар е чакане;

    var ExecuteFunc = функция (парами) {
        isWaiting = true;
        функция (PARAMS);
        setTimeout (игра, изчакване);
    };

    var play = функция () {
        isWaiting = невярно;
        ако (funcQueue.length) {
            var params = funcQueue.shift ();
            executeFunc (PARAMS);
        }
    };

    функция за връщане (парами) {
        ако (isWaiting) {
            funcQueue.push (PARAMS);
        } else {
            executeFunc (PARAMS);
        }
    }
};

В заключение

Преди да решите техниката на оптимизация, направете крачка назад и помислете кой от тях ще даде най-добрия резултат за този случай. Винаги има такава, която ще бъде по-ефективна.

Моля, не се колебайте да оставите отговор или да ме чукате с въпроси или предложения.