Kifejtett visszavonás - Hogyan lehet a JavaScriptet megvárni, amíg a felhasználó befejezi a gépelést

A JavaScript visszavonási funkciói magasabb rendű függvények, amelyek korlátozzák egy másik függvény hívásának sebességét.

A magasabb rendű függvény olyan függvény, amely vagy függvényt vesz fel argumentumként, vagy pedig egy függvényt ad vissza a return utasítás részeként. Visszavonási funkciónk mindkettőt elvégzi.

A visszavonás leggyakoribb használati esete, ha argumentumként továbbítja azt egy HTML elemhez csatolt eseményhallgatónak. Annak érdekében, hogy jobban megértsük, hogyan néz ki, és miért hasznos, nézzünk meg egy példát.

Tegyük fel, hogy van egy nevű függvénye myFunc, amelyet minden alkalommal meghívunk, amikor valamit begépel egy beviteli mezőbe. Miután áttekintette a projekt követelményeit, úgy dönt, hogy változtatni kíván a tapasztalaton.

Ehelyett akkor akar myFuncvégrehajtani, amikor legalább 2 másodperc telt el azóta, hogy utoljára beírtál valamit.

Itt jöhet szóba egy visszavágás. Ahelyett, hogy átadná myFuncaz eseményhallgatónak , átadná a visszavonást. Maga a visszavágás myFuncérvként szolgálna , a 2000-es számmal együtt.

Most, amikor a gombra kattint, myFunccsak akkor hajt végre, ha legalább 2 másodperc telt el az utolsó myFunchívás előtt.

A visszavonási funkció megvalósítása

Az elejétől a végéig csak 7 kódsor kell a visszavonási funkció megvalósításához. A szakasz további része arra a 7 kódsorra összpontosít, hogy lássuk, hogyan működik belső visszavonási funkciónk.

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

Az 1. sortól kezdve deklaráltunk egy új nevű függvényt debounce. Ennek az új funkciónak két paramétere van, callbackés delay.

function debounce( callback, delay ) { } 

callback bármely olyan funkció, amelynek korlátoznia kell a végrehajtások számát.

delayaz az idő (ezredmásodpercben), amelynek el kell telnie, mielőtt callbackújra végrehajtaná.

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

A 2. sorban egy inicializálatlan változót deklarálunk timeout.

Ez az új változó megtartja a timeoutIDvisszaadott értéket, ha setTimeoutkésőbb a debouncefunkciónkban hívjuk meg .

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

A 3. vonalon egy névtelen funkciót adunk vissza. Ez a névtelen függvény bezárul a timeoutváltozó fölött , hogy hozzáférést is megőrizhessünk ahhoz, hogy az első hívás debouncebefejeződött volna.

A JavaScript bezárása akkor következik be, amikor egy belső függvény hozzáférést biztosít külső funkciójának lexikális hatóköréhez, annak ellenére, hogy a külső függvény befejeződött. Ha többet szeretne megtudni a bezárásokról, olvassa el Kyle Simpson „Nem ismered JS-t” 7. fejezetét
function debounce( callback, delay ) { let timeout; return function() { clearTimeout( timeout ); } }

A 4-es vonalon hívjuk clearTimeouta WindowOrWorkerGlobalScopemixin módszerét . Ez biztosítja, hogy minden alkalommal, amikor meghívjuk a debouncefunkciónkat, timeoutnullázásra kerül, és a számláló újra indulhat.

A WindowOrWorkerGlobalScopemixin JavaScript enged hozzáférést néhány jól ismert módszerekkel, például setTimeout, clearTimeout, setInterval, clearInterval, és fetch.

A cikk elolvasásával többet tudhat meg róla.

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

Az 5-ös vonalon elértük a debouncefunkciók megvalósításának végét .

Ez a kódsor néhány dolgot végez. Az első lépés egy érték hozzárendelése ahhoz a timeoutváltozóhoz, amelyet a 2. sorban deklaráltunk. Az érték egy, timeoutIDamely visszatér, amikor hívunk setTimeout. Ez lehetővé teszi számunkra, hogy hivatkozzunk a hívással létrehozott időkorlátra setTimeout, hogy a debouncefunkciónk minden használatakor visszaállíthassuk .

A második végrehajtott művelet hívás setTimeout. Ez létrehoz egy időtúllépést, amely egyszer (a függvényünknek átadott szám argumentum ) letelt callback(a függvényünknek átadott funkció argumentum ) letelt.debouncedelaydebounce

Mivel időtúllépést használunk, callbackcsak akkor fog végrehajtódni, ha hagyjuk, hogy az időkorlát elérje a 0. Ez a debouncefunkciónk szíve játszik szerepet, mivel az egyes időkorlátokat minden alkalommal visszaállítjuk debounce. Ez lehetővé teszi számunkra, hogy korlátozzuk a myFunc.

Az 5. és 6. sor csak zárójeleket tartalmaz, ezért nem lépjük át őket.

Ez az. Funkciónk így debounceműködik belsőleg. Most tegyük hozzá az elejétől az előző példánkat. Létrehozunk egy beviteli mezőt, és egy eseményfigyelőt csatolunk a debouncefüggvényünkkel az egyik érvként.

Példa a valós világra

Először létre kell hoznunk egy beviteli mezőt.

Type something in! 

Ezután létre kell hoznunk egy olyan függvényt, amelyet végre akarunk hajtani, amikor valamit beírunk a beviteli mezőbe.

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

Végül ki kell választanunk a fent létrehozott beviteli mezőt, és hozzá kell csatolnunk egy keyupeseményfigyelőt.

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

Ezzel befejezzük valós világunk példáját! Valahányszor beírunk valamit a beviteli mezőbe, helloWorldakkor végrehajtásra kerül, ha legalább 2 másodperc telt el azóta, hogy utoljára beírtunk valamit.

Külön köszönet a Reddit felhasználói sztratoszkópnak, hogy segített kijavítani a cikkben szereplő kezdeti kódot. Itt van egy működő bemutató, amelyet erről a debouncefunkcióról készített a Repl.it webhelyen.

Záró megjegyzések

A visszavonási funkciók egyszerűek, ugyanakkor hatékonyak, és észrevehetően befolyásolhatják a legtöbb JavaScript alkalmazást.

Míg példánk szórakoztató és egyértelmű volt, sok nagy szervezet a visszavonási funkciókat használja az alkalmazások teljesítményének növelésére.

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