Afregning forklaret - Sådan får du din JavaScript til at vente på, at din bruger afslutter at skrive

Afvisningsfunktioner i JavaScript er højere ordensfunktioner, der begrænser den hastighed, hvormed en anden funktion bliver kaldt.

En højere ordensfunktion er en funktion, der enten tager en funktion som et argument eller returnerer en funktion som en del af dens returneringserklæring. Vores afvisningsfunktion gør begge dele.

Den mest almindelige brugssag til en afvisning er at videregive den som et argument til en begivenhedslytter, der er knyttet til et HTML-element. For at få en bedre forståelse af, hvordan dette ser ud, og hvorfor det er nyttigt, lad os se på et eksempel.

Sig, at du har en funktion med navnet, myFuncder bliver kaldt, hver gang du skriver noget i et indtastningsfelt. Efter at have gennemgået kravene til dit projekt, beslutter du, at du vil ændre oplevelsen.

I stedet vil myFuncdu udføre, når der er gået mindst 2 sekunder siden sidste gang du skrev noget.

Det er her, en afvisning kan komme i spil. I stedet for at videregive myFunctil begivenhedslytteren, vil du give afvisning. Selve afvisningen ville derefter tage myFuncsom et argument sammen med tallet 2000.

Hver gang du klikker på knappen, myFuncvil den kun udføres, hvis der er gået mindst 2 sekunder, inden sidste gang myFuncblev kaldt.

Sådan implementeres en afvisningsfunktion

Fra start til slut tager det kun 7 linjer kode at implementere en afvisningsfunktion. Resten af ​​dette afsnit fokuserer på de 7 kodelinjer, så vi kan se, hvordan vores afvisningsfunktion fungerer internt.

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

Startende med linje 1 har vi erklæret en ny funktion med navnet debounce. Denne nye funktion har to parametre, callbackog delay.

function debounce( callback, delay ) { } 

callback er enhver funktion, der skal begrænse antallet af gange, den udføres.

delayer tiden (i millisekunder), der skal gå, før den callbackkan udføres igen.

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

På linje 2 erklærer vi en ikke-initialiseret variabel med navnet timeout.

Denne nye variabel holder timeoutIDreturneret, når vi setTimeoutsenere kalder op i vores debouncefunktion.

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

På linje 3 returnerer vi en anonym funktion. Denne anonyme funktion lukkes over timeoutvariablen, så vi kan bevare adgangen til den, selv efter at det første opkald til debounceer færdig med at blive udført.

En lukning i JavaScript opstår, når en indre funktion bevarer adgang til det leksikale omfang af sin ydre funktion, selvom den ydre funktion er færdig med at blive udført. Hvis du vil lære mere om lukninger, kan du læse kapitel 7 i “Du kender ikke JS” af Kyle Simpson
function debounce( callback, delay ) { let timeout; return function() { clearTimeout( timeout ); } }

På linje 4 kalder vi clearTimeoutmetoden til WindowOrWorkerGlobalScopemixin. Dette vil sikre, at hver gang vi kalder vores debouncefunktion, timeoutnulstilles, og tælleren kan starte igen.

Den WindowOrWorkerGlobalScopeMixIn af JavaScript giver os adgang til et par velkendte metoder, ligesom setTimeout, clearTimeout, setInterval, clearInterval, og fetch.

Du kan lære mere om det ved at læse denne artikel.

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

På linje 5 har vi nået slutningen af ​​vores debouncefunktionsimplementering.

Denne kodelinje gør et par ting. Den første handling er at tildele en værdi til den timeoutvariabel, som vi erklærede på linje 2. Værdien er en, timeoutIDder returneres, når vi ringer setTimeout. Dette giver os mulighed for at henvise til den timeout, der oprettes ved at ringe, setTimeoutså vi kan nulstille den hver gang vores debouncefunktion bruges.

Den anden udførte handling kalder setTimeout. Dette skaber en timeout, der udføres callback(funktionsargumentet videregivet til vores debouncefunktion), når delaynummerargumentet videregivet til vores debouncefunktion er forløbet.

Da vi bruger en timeout, callbackvil den kun udføres, hvis vi tillader, at timeout'en når 0. Dette er, hvor hjertet i vores debouncefunktion kommer i spil, da vi nulstiller timeout, hver gang debounceder kaldes. Dette er det, der giver os mulighed for at begrænse udførelsesgraden på myFunc.

Linje 5 og 6 indeholder kun parenteser, så vi går ikke over dem.

Det er det. Sådan fungerer vores debouncefunktion internt. Lad os nu tilføje vores tidligere eksempel fra starten. Vi skal oprette et inputfelt og vedhæfte en begivenhedslytter med vores debouncefunktion som et af dens argumenter.

Virkelig verdenseksempel

Først skal vi oprette et inputfelt.

Type something in! 

Dernæst skal vi oprette en funktion, som vi vil udføre, når vi skriver noget i vores inputfelt.

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

Endelig skal vi vælge det inputfelt, vi oprettede ovenfor, og vedhæfte en keyupbegivenhedslytter til det.

const myInput = document.getElementById("myInput"); myInput.addEventListener( "keyup", debounce( helloWorld, 2000 ) );

Det afslutter vores virkelige verdenseksempel! Hver gang vi skriver noget i vores indtastningsfelt, helloWorldudføres, hvis der er gået mindst 2 sekunder siden sidste gang vi indtastede noget.

Særlig tak til Reddit bruger stratoscope for at hjælpe med at løse nogle af de indledende kode i denne artikel. Her er en fungerende demo, han oprettede af denne debouncefunktion på Repl.it.

Afsluttende noter

Afvisningsfunktioner er enkle, men alligevel kraftfulde funktioner, der kan have en mærkbar indflydelse på de fleste JavaScript-applikationer.

Mens vores eksempel var sjovt og ligetil, bruger mange store organisationer afvisningsfunktioner til at øge deres applikations ydeevne.

Hvis du vil lære mere om JavaScript, skal du tjekke min hjemmeside! Jeg arbejder på nogle seje ting på //juanmvega.com.