Model vykonávania JavaScriptu je nuansovaný a ľahko nepochopiteľný. Pomôcť môže poznanie slučky udalostí v jej jadre.

JavaScript je jednovláknový jazyk vytvorený tak, aby zvládal úlohy jednu po druhej. Slučka udalostí však umožňuje JavaScriptu spracovávať udalosti a spätné volania asynchrónne emuláciou simultánnych programovacích systémov. To zaisťuje výkon vašich aplikácií JavaScript.

Čo je to slučka udalostí JavaScript?

Slučka udalostí JavaScriptu je mechanizmus, ktorý beží na pozadí každej aplikácie JavaScript. Umožňuje JavaScriptu spracovávať úlohy v poradí bez blokovania jeho hlavného vykonávacieho vlákna. Toto sa označuje ako asynchrónne programovanie.

Slučka udalostí udržiava rad úloh na spustenie a posúva tieto úlohy doprava webové rozhranie API na vykonanie po jednom. JavaScript sleduje tieto úlohy a spracováva každú podľa úrovne zložitosti úlohy.

Aby sme pochopili potrebu slučky udalostí JavaScriptu a asynchrónneho programovania. Musíte pochopiť, aký problém to v podstate rieši.

Vezmite napríklad tento kód:

instagram viewer
functionlongRunningFunction() {
// This function does something that takes a long time to execute.
for (var i = 0; i < 100000; i++) {
console.log("Hello")
}
}

functionshortRunningFunction(a) {
return a * 2 ;
}

functionmain() {
var startTime = Date.now();
longRunningFunction();

var endTime = Date.now();

// Prints the amount of time it took to execute functions
console.log(shortRunningFunction(2));
console.log("Time taken: " + (endTime - startTime) + " milliseconds");
}

main();

Tento kód najskôr definuje funkciu tzv longRunningFunction(). Táto funkcia vykoná nejakú zložitú a časovo náročnú úlohu. V tomto prípade vykonáva a pre opakovanie cyklu viac ako 100 000 krát. To znamená, že console.log("Ahoj") prebehne 100 000 krát.

V závislosti od rýchlosti počítača to môže trvať dlho a zablokovať sa shortRunningFunction() od okamžitého vykonania až po dokončenie predchádzajúcej funkcie.

Pre kontext je tu porovnanie času potrebného na spustenie oboch funkcií:

A potom singel shortRunningFunction():

Rozdiel medzi 2 351-milisekundovou operáciou a 0-milisekundovou operáciou je zrejmý, keď sa snažíte vytvoriť výkonnú aplikáciu.

Ako slučka udalostí pomáha s výkonom aplikácie

Slučka udalostí má rôzne fázy a časti, ktoré prispievajú k fungovaniu systému.

Zásobník hovorov

Zásobník volaní JavaScriptu je nevyhnutný na to, ako JavaScript spracováva volania funkcií a udalostí z vašej aplikácie. Kód JavaScript sa kompiluje zhora nadol. Node.js však pri čítaní kódu priradí volanie funkcií zdola nahor. Počas čítania posúva definované funkcie ako rámce do zásobníka hovorov jeden po druhom.

Zásobník hovorov je zodpovedný za udržiavanie kontextu vykonávania a správneho poradia funkcií. Robí to tak, že funguje ako zásobník Last-In-First-Out (LIFO).

To znamená, že posledný funkčný rámec, ktorý váš program vloží do zásobníka hovorov, bude prvý, ktorý vyskočí zo zásobníka a spustí sa. To zabezpečí, že JavaScript zachová správne poradie vykonávania funkcií.

JavaScript bude vyskakovať každý rámec zo zásobníka, kým nebude prázdny, čo znamená, že všetky funkcie sa skončili.

Libuv Web API

Jadrom asynchrónnych programov JavaScriptu je libuv. Knižnica libuv je napísaná v programovacom jazyku C, ktorý môže interagovať s operačným systémom nízkoúrovňové API. Knižnica bude poskytovať niekoľko rozhraní API, ktoré umožňujú súbežné spustenie kódu JavaScript s inými kód. API na vytváranie vlákien, API na komunikáciu medzi vláknami a API na správu synchronizácie vlákien.

Napríklad, keď používate setTimeout v Node.js na pozastavenie vykonávania. Časovač sa nastavuje cez libuv, ktorý riadi slučku udalostí tak, aby vykonala funkciu spätného volania po uplynutí špecifikovaného oneskorenia.

Podobne, keď vykonávate sieťové operácie asynchrónne, libuv spracováva tieto operácie bez blokovania spôsobom, ktorý zaisťuje, že ostatné úlohy môžu pokračovať v spracovaní bez čakania na operáciu vstupu/výstupu (I/O). koniec.

Spätné volanie a front udalostí

Front spätných volaní a udalostí je miesto, kde funkcie spätného volania čakajú na vykonanie. Po dokončení asynchrónnej operácie z libuv sa do tohto frontu pridá zodpovedajúca funkcia spätného volania.

Poradie prebieha takto:

  1. JavaScript presúva asynchrónne úlohy do libuv, aby ich mohol zvládnuť, a okamžite pokračuje v spracovávaní ďalšej úlohy.
  2. Po dokončení asynchrónnej úlohy JavaScript pridá svoju funkciu spätného volania do frontu spätných volaní.
  3. JavaScript stále vykonáva ďalšie úlohy v zásobníku hovorov, kým sa neskončí so všetkým v aktuálnom poradí.
  4. Keď je zásobník hovorov prázdny, JavaScript sa pozrie na front spätných volaní.
  5. Ak je vo fronte spätné volanie, zatlačí prvé do zásobníka hovorov a vykoná ho.

Týmto spôsobom asynchrónne úlohy neblokujú hlavné vlákno a front spätných volaní zaisťuje, že ich zodpovedajúce spätné volania sa vykonajú v poradí, v akom boli dokončené.

Cyklus slučky udalostí

Slučka udalostí má tiež niečo, čo sa nazýva front mikroúloh. Tento špeciálny rad v slučke udalostí obsahuje mikroúlohy naplánované na vykonanie hneď po dokončení aktuálnej úlohy v zásobníku hovorov. Toto spustenie sa uskutoční pred ďalšou iteráciou vykresľovania alebo slučky udalostí. Mikroúlohy sú úlohy s vysokou prioritou, ktoré majú prednosť pred bežnými úlohami v slučke udalostí.

Mikroúloha sa bežne vytvára pri práci s Promises. Vždy, keď je prísľub vyriešený alebo zamietnutý, zodpovedá tomu .potom() alebo .catch() spätné volania sa pripájajú do frontu mikroúloh. Tento front môžete použiť na manažovanie úloh, ktoré vyžadujú okamžité vykonanie po aktuálnej operácii, ako je aktualizácia používateľského rozhrania vašej aplikácie alebo spracovanie zmien stavu.

Napríklad webová aplikácia, ktorá vykonáva načítanie údajov a aktualizuje používateľské rozhranie na základe získaných údajov. Používatelia môžu spustiť toto načítanie údajov opakovaným kliknutím na tlačidlo. Každé kliknutie na tlačidlo spustí operáciu asynchrónneho načítania údajov.

Bez mikroúloh by slučka udalostí pre túto úlohu fungovala takto:

  1. Používateľ opakovane kliká na tlačidlo.
  2. Každé kliknutie na tlačidlo spustí operáciu asynchrónneho načítania údajov.
  3. Po dokončení operácií načítania údajov JavaScript pridá ich zodpovedajúce spätné volania do bežného frontu úloh.
  4. Slučka udalostí spustí spracovanie úloh v bežnom fronte úloh.
  5. Aktualizácia používateľského rozhrania na základe výsledkov načítania údajov sa vykoná hneď, ako to bežné úlohy umožňujú.

Pri mikroúlohách však slučka udalostí funguje inak:

  1. Používateľ opakovane klikne na tlačidlo a spustí operáciu asynchrónneho načítania údajov.
  2. Po dokončení operácií načítania údajov slučka udalostí pridá svoje zodpovedajúce spätné volania do frontu mikroúloh.
  3. Slučka udalostí začne spracovávať úlohy vo fronte mikroúloh ihneď po dokončení aktuálnej úlohy (kliknutie na tlačidlo).
  4. Aktualizácia používateľského rozhrania na základe výsledkov načítania údajov sa vykoná pred ďalšou pravidelnou úlohou, čo poskytuje pohotovejšie používateľské prostredie.

Tu je príklad kódu:

const fetchData = () => {
returnnewPromise(resolve => {
setTimeout(() => resolve('Data from fetch'), 2000);
});
};

document.getElementById('fetch-button').addEventListener('click', () => {
fetchData().then(data => {
// This UI update will run before the next rendering cycle
updateUI(data);
});
});

V tomto príklade zavolá každé kliknutie na tlačidlo „Načítať“. fetchData(). Každá operácia načítania údajov je naplánovaná ako mikroúloha. Na základe načítaných údajov sa aktualizácia používateľského rozhrania vykoná okamžite po dokončení každej operácie načítania, pred akýmikoľvek inými úlohami vykresľovania alebo slučky udalostí.

To zaisťuje, že používatelia uvidia aktualizované údaje bez akýchkoľvek oneskorení v dôsledku iných úloh v slučke udalostí.

Používanie mikroúloh v scenároch, ako je tento, môže zabrániť trhaniu používateľského rozhrania a poskytnúť rýchlejšie a plynulejšie interakcie vo vašej aplikácii.

Dôsledky slučky udalostí pre vývoj webu

Pochopenie slučky udalostí a spôsobu používania jej funkcií je nevyhnutné na vytváranie výkonných a pohotových aplikácií. Slučka udalostí poskytuje asynchrónne a paralelné možnosti, takže môžete efektívne zvládnuť zložité úlohy vo svojej aplikácii bez toho, aby ste ohrozili používateľskú skúsenosť.

Node.js poskytuje všetko, čo potrebujete, vrátane webových pracovníkov na dosiahnutie ďalšieho paralelizmu mimo hlavného vlákna JavaScriptu.