Objašnjeno odbijanje - Kako natjerati JavaScript da pričeka da vaš korisnik završi s tipkanjem

Funkcije otpuštanja u JavaScript-u su funkcije višeg reda koje ograničavaju brzinu poziva druge funkcije.

Funkcija višeg reda je funkcija koja ili uzima funkciju kao argument ili vraća funkciju kao dio svog izraza return. Naša funkcija otkazivanja čini oboje.

Najčešći slučaj upotrebe debouncea je prosljeđivanje kao argumenta preslušaču događaja pridruženom HTML elementu. Da bismo bolje razumjeli kako to izgleda i zašto je korisno, pogledajmo primjer.

Recimo da imate funkciju myFunckoja se zove koja se poziva svaki put kad nešto upišete u polje za unos. Nakon što prođete kroz zahtjeve za svoj projekt, odlučite da želite promijeniti iskustvo.

Umjesto toga, želite myFuncizvršiti kada prođu najmanje 2 sekunde od posljednjeg unosa.

Ovdje dolazi do izražaja limenka s otkazom. Umjesto da pređete myFuncna slušatelja događaja, vi biste prešli u zapis. Sama myFuncrasprava tada bi uzela kao argument, zajedno s brojem 2000.

Sad, kad god kliknete gumb, myFuncizvršit će se samo ako su protekle najmanje 2 sekunde prije zadnjeg myFuncpoziva.

Kako implementirati funkciju debouncea

Od početka do kraja, potrebno je samo 7 redaka koda da bi se implementirala funkcija otkazivanja. Ostatak ovog odjeljka fokusira se na tih 7 redaka koda kako bismo mogli vidjeti kako naša funkcija otkazivanja interno djeluje.

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

Počevši od retka 1, proglasili smo novu funkciju imenovanu debounce. Ova nova funkcija ima dva parametra, callbacki delay.

function debounce( callback, delay ) { } 

callback je bilo koja funkcija koja treba ograničiti broj izvršavanja.

delayje vrijeme (u milisekundama) koje treba proteći prije nego što se callbackmože ponovno izvršiti.

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

U retku 2 deklariramo neinicijaliziranu varijablu s imenom timeout.

Ova nova varijabla zadržava timeoutIDvraćeno kada setTimeoutkasnije zovemo u našoj debouncefunkciji.

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

U retku 3 vraćamo anonimnu funkciju. Ova anonimna funkcija zatvorit će se nad timeoutvarijablom tako da joj možemo zadržati pristup čak i nakon debouncezavršetka izvršenja početnog poziva na .

Do zatvaranja u JavaScript dolazi kad god unutarnja funkcija zadrži pristup leksičkom opsegu svoje vanjske funkcije, iako je vanjska funkcija završila s izvršavanjem. Ako želite saznati više o zatvaranju, možete pročitati 7. poglavlje "Ne znaš JS" Kylea Simpsona
function debounce( callback, delay ) { let timeout; return function() { clearTimeout( timeout ); } }

Na liniji 4 nazivamo clearTimeoutmetodu WindowOrWorkerGlobalScopemiješanja. To će osigurati da se svaki put kada pozovemo našu debouncefunkciju timeoutresetira i brojač može ponovno pokrenuti.

WindowOrWorkerGlobalScopeMixin JavaScript nam daje pristup nekoliko dobro poznatih metoda, kao što su setTimeout, clearTimeout, setInterval, clearInterval, i fetch.

O tome možete saznati više čitajući ovaj članak.

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

Na liniji 5 stigli smo do kraja debounceimplementacije naše funkcije.

Taj redak koda čini nekoliko stvari. Prva radnja je dodjela vrijednosti timeoutvarijabli koju smo deklarirali u retku 2. Vrijednost je vrijednost timeoutIDkoja se vraća kada pozovemo setTimeout. To će nam omogućiti referencu na vremensko ograničenje stvoreno pozivanjem setTimeoutkako bismo ga mogli resetirati svaki put kada debouncese koristi naša funkcija.

Druga izvedena radnja je pozivanje setTimeout. To će stvoriti vremensko ograničenje koje će se izvršiti callback(argument funkcije proslijeđen našoj debouncefunkciji) nakon što protekne delay(argument proslijeden našoj debouncefunkciji).

Budući da koristimo vremensko ograničenje, callbackizvršit će se samo ako dopustimo da vremensko ograničenje dosegne 0. Tu dolazi do izražaja srž naše debouncefunkcije budući da se svaki put kada debouncese poziv resetira resetira . To je ono što nam omogućuje da ograničimo brzinu izvršenja myFunc.

Redci 5 i 6 sadrže samo zagrade, pa ih nećemo prelaziti.

To je to. Tako naša debouncefunkcija funkcionira interno. Sad dodajmo naš prethodni primjer od početka. Stvorit ćemo polje za unos i priložiti slušatelj događaja s našom debouncefunkcijom kao jednim od njegovih argumenata.

Primjer iz stvarnog svijeta

Prvo, moramo stvoriti polje za unos.

Type something in! 

Dalje, moramo stvoriti funkciju koju želimo izvršiti kad god nešto upišemo u svoje polje za unos.

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

Na kraju, trebamo odabrati polje za unos koje smo gore stvorili i na njega priložiti keyupslušatelj događaja.

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

To zaključuje naš primjer iz stvarnog svijeta! Svaki put kad nešto upišemo u svoje polje za unos, helloWorldizvršit će se ako su prošle posljednje najmanje 2 sekunde od zadnjeg unosa .

Posebna zahvala Redditovom stratoskopu za pomoć u popravljanju nekog početnog koda u ovom članku. Evo radne demonstracije koju je stvorio za ovu debouncefunkciju na Repl.it.

Završne napomene

Funkcije otpuštanja jednostavne su, ali moćne funkcije koje mogu imati primjetan utjecaj na većinu JavaScript aplikacija.

Iako je naš primjer bio zabavan i izravan, mnoge velike organizacije koriste funkcije odbacivanja kako bi povećale izvedbu svojih aplikacija.

If you want to learn more about JavaScript, check out my website! I am working on some cool stuff at //juanmvega.com.