Funcțiile de respingere din JavaScript sunt funcții de ordin superior care limitează rata la care este apelată o altă funcție.

O funcție de ordin superior este o funcție care fie ia o funcție ca argument, fie returnează o funcție ca parte a instrucțiunii sale return. Funcția noastră de retragere le face pe ambele.

Cel mai frecvent caz de utilizare pentru un debounce este de a-l transmite ca argument unui ascultător de evenimente atașat unui element HTML. Pentru a înțelege mai bine cum arată acest lucru și de ce este util, să analizăm un exemplu.

Spuneți că aveți o funcție numită myFunc care este apelat de fiecare dată când introduceți ceva într-un câmp de intrare. După ce parcurgeți cerințele pentru proiectul dvs., decideți că doriți să schimbați experiența.

În schimb, vrei myFunc pentru a executa când au trecut cel puțin 2 secunde de la ultima dată când ați introdus ceva.

Aici intră în joc o cutie de dezbatere. În loc să treacă myFunc ascultătorului de evenimente, ați trece în debounce. Decontul în sine ar lua apoi myFunc ca argument, împreună cu numărul 2000.

Acum, ori de câte ori faceți clic pe buton, myFunc se va executa numai dacă au trecut cel puțin 2 secunde înainte de ultima dată myFunc a fost chemat.

Cum se implementează o funcție de debounce

De la început până la sfârșit, sunt necesare doar 7 linii de cod pentru a implementa o funcție de debounce. Restul acestei secțiuni se concentrează pe aceste 7 linii de cod, astfel încât să putem vedea cum funcționează funcția noastră de debounce intern.

function debounce( callback, delay ) {
    let timeout;
    return function() {
        clearTimeout( timeout );
        timeout = setTimeout( callback, delay );
    }
}

Începând cu linia 1, am declarat o nouă funcție numită debounce. Această nouă funcție are doi parametri, callback și delay.

function debounce( callback, delay ) {

}

callback este orice funcție care trebuie să limiteze de câte ori se execută.

delay este timpul (în milisecunde) care trebuie să treacă înainte callback poate executa din nou.

function debounce( callback, delay ) {
    let timeout;
}

Pe linia 2, declarăm o variabilă neinițializată numită timeout.
Această nouă variabilă deține timeoutID întors când sunăm setTimeout mai târziu în debounce funcţie.

function debounce( callback, delay ) {
    let timeout;
    return function() {
    }
}

Pe linia 3, returnăm o funcție anonimă. Această funcție anonimă se va închide peste timeout variabilă, astfel încât să putem păstra accesul la aceasta chiar și după apelul inițial către debounce a terminat executarea.

O închidere în JavaScript apare ori de câte ori o funcție interioară păstrează accesul la sfera lexicală a funcției sale externe, chiar dacă funcția exterioară a terminat de executat. Dacă doriți să aflați mai multe despre închideri, puteți citi Capitolul 7 din „Nu știi JS” de Kyle Simpson

function debounce( callback, delay ) {
    let timeout;
    return function() {
        clearTimeout( timeout );
    }
}

Pe linia 4, apelăm la clearTimeout metoda WindowOrWorkerGlobalScope mixin. Acest lucru ne va asigura că de fiecare dată când îl sunăm pe al nostru debounce funcţie, timeout este resetat, iar contorul poate porni din nou.

WindowOrWorkerGlobalScope mixin de JavaScript ne oferă acces la câteva metode bine cunoscute, cum ar fi setTimeout, clearTimeout, setInterval, clearInterval, și fetch.

Puteți afla mai multe despre aceasta citind acest articol.

function debounce( callback, delay ) {
    let timeout;
    return function() {
        clearTimeout( timeout );
        timeout = setTimeout( callback, delay );
    }
}

Pe linia 5, am ajuns la sfârșitul nostru debounce implementarea funcției.

Această linie de cod face câteva lucruri. Prima acțiune este atribuirea unei valori pentru timeout variabilă pe care am declarat-o pe linia 2. Valoarea este a timeoutID care se returnează când sunăm setTimeout. Acest lucru ne va permite să facem referire la timeout-ul creat prin apelare setTimeout astfel încât să-l putem reseta de fiecare dată când debounce este utilizată funcția.

A doua acțiune efectuată este apelarea setTimeout. Aceasta va crea un timeout care se va executa callback (argumentul funcției a trecut la debounce funcție) o dată delay (argumentul numărului a trecut la debounce funcție) s-a scurs.

Deoarece folosim un timeout, callback se va executa numai dacă permitem ca timpul de expirare să ajungă la 0. Aici este inima noastră debounce funcția intră în joc, deoarece resetăm timpul de expirare de fiecare dată debounce se numește. Acesta este ceea ce ne permite să limităm rata de execuție a myFunc.

Liniile 5 și 6 conțin numai paranteze, deci nu le vom trece peste ele.

Asta este. Așa este debounce funcția funcționează intern. Acum să adăugăm la exemplul nostru anterior de la început. Vom crea un câmp de introducere și vom atașa un ascultător de evenimente cu debounce funcționează ca unul dintre argumentele sale.

Exemplu de lume reală

În primul rând, trebuie să creăm un câmp de intrare.

<label for="myInput">Type something in!</label>
<input id="myInput" type="text">

Apoi, trebuie să creăm o funcție pe care dorim să o executăm ori de câte ori introducem ceva în câmpul nostru de intrare.

function helloWorld() {
    console.log("Hello World!")
}

În cele din urmă, trebuie să selectăm câmpul de intrare pe care l-am creat mai sus și să atașăm un keyup ascultător de evenimente.

const myInput = document.getElementById("myInput");

myInput.addEventListener(
    "keyup",
    debounce( helloWorld, 2000 )
);

Asta încheie exemplul nostru din lumea reală! De fiecare dată când introducem ceva în câmpul nostru de intrare, helloWorld se va executa dacă au trecut cel puțin 2 secunde de la ultima dată când am introdus ceva.

Mulțumiri speciale utilizatorului Reddit stratoscop pentru a ajuta la remedierea unora dintre codurile inițiale din acest articol. Iată un demo de lucru el a creat din aceasta debounce funcție pe Repl.it.

Note de închidere

Funcțiile Debounce sunt funcții simple, dar puternice, care pot avea un impact vizibil asupra majorității aplicațiilor JavaScript.

În timp ce exemplul nostru a fost amuzant și simplu, multe organizații mari folosesc funcții de respingere pentru a spori performanța aplicațiilor lor.

Dacă doriți să aflați mai multe despre JavaScript, consultați site-ul meu web! Lucrez la niște chestii interesante la https://juanmvega.com.