Ako funguje Event Loop v JavaScripte?

Aj keď písanie úplného produkčného kódu môže vyžadovať dôkladné porozumenie jazykov ako C ++ a C, často sa dá písať iba so základným porozumením toho, čo sa dá s jazykom urobiť..


Koncepty, ako napríklad odovzdávanie spätných volaní funkciám alebo písanie asynchrónneho kódu, sa často nedajú tak ťažko implementovať, čo väčšine vývojárov jazyka JavaScript menej zaujíma o to, čo sa deje pod kapotou. Nezaujíma sa iba o pochopenie komplexností, ktoré od nich jazyk hlboko abstrahoval.

Ako vývojár JavaScriptu je čoraz dôležitejšie porozumieť tomu, čo sa skutočne deje pod kapotou a ako väčšina týchto komplikácií od nás skutočne funguje. Pomáha nám prijímať informovanejšie rozhodnutia, čo môže zase výrazne zvýšiť výkonnosť nášho kódu.

Tento článok sa zameriava na jeden z veľmi dôležitých, ale zriedka pochopených konceptov alebo výrazov v JavaScripte. UDALOSTI OBRAZU!. 

V jazyku JavaScript sa nedá vyhnúť písaniu asynchrónneho kódu, ale prečo to znamená, že kód, ktorý beží asynchrónne, naozaj znamená? tj. Cyklus udalostí

Predtým, ako pochopíme, ako slučka udalostí funguje, musíme najprv pochopiť, čo je samotný JavaScript a ako to funguje!

Čo je to JavaScript?

Než budeme pokračovať, bol by som rád, keby sme urobili krok späť k samotným základom. Čo je to skutočne JavaScript? JavaScript by sme mohli definovať ako;

JavaScript je vysoko interpretovaný jednovláknový neblokujúci asynchrónny súbežný jazyk.

Počkaj, čo je to? Zrozumiteľná definícia? ��

Poďme to rozobrať!

Kľúčové slová v tomto článku sú jednovláknových, neblokujúce, súbežné, a asynchrónne.

Jedno vlákno

Vlákno vykonávania je najmenšia sekvencia naprogramovanej inštrukcie, ktorá môže byť riadená nezávisle plánovačom. Programovací jazyk je jednovláknový, čo znamená, že dokáže naraz vykonať iba jednu úlohu alebo operáciu. To znamená, že by vykonal celý proces od začiatku do konca bez prerušenia alebo zastavenia vlákna.

Na rozdiel od viacvláknových jazykov, kde je možné súčasne spúšťať viacero procesov na viacerých vláknach bez vzájomného blokovania.

Ako môže byť JavaScript s jedným vláknom a neblokujúca v rovnaký čas?

Čo to znamená blokovanie?

Neblokujúca

Neexistuje žiadna definícia blokovania; znamená to jednoducho veci, ktoré na vlákne bežia pomaly. Neblokovanie teda znamená veci, ktoré na vlákne nespomalia.

Ale počkajte, povedal som, že JavaScript beží na jednom vlákne? A tiež som povedal, že neblokuje, čo znamená, že úloha sa rýchlo spúšťa v zásobníku hovorov? Ale ako??? A čo keď spustíme časovače? Loops?

Relax! Trochu sme to zistili find.

súbežný

Súbežnosť znamená, že kód sa vykonáva súbežne s viacerými vláknami.

Dobre, veci sa stávajú skutočne skutočné príšerný Ako teraz môže byť JavaScript jednovláknový a súbežný súčasne? t. j. vykonanie jeho kódu s viac ako jedným vláknom?

asynchrónne

Asynchrónne programovanie znamená, že kód beží v slučke udalostí. Ak dôjde k blokovacej operácii, udalosť sa spustí. Blokovací kód stále beží bez blokovania hlavného vlákna vykonávania. Keď sa blokovací kód dokončí, je vo fronte výsledkom blokovacích operácií a tlačí ich späť do zásobníka.

Ale JavaScript má jedno vlákno? Čo potom vykoná tento blokovací kód a zároveň nechá vykonať ďalšie kódy vo vlákne?

Skôr ako budeme pokračovať, urobme zhrnutie vyššie uvedeného.

  • JavaScript je jednovláknový
  • JavaScript neblokuje, t. J. Jeho pomalé procesy neblokujú jeho vykonanie
  • JavaScript je súbežný, t. J. Vykonáva svoj kód vo viac ako jednom vlákne súčasne
  • JavaScript je asynchrónny, t. J. Spúšťa blokovací kód niekde inde.

Avšak vyššie uvedené presne nevysvetľuje, ako môže byť jazyk s jedným vláknom neblokujúci, súbežný a asynchrónny?

Poďme trochu hlbšie, poďme dole na runtime moduly JavaScript, V8, možno má nejaké skryté vlákna, o ktorých nevieme.

Motor V8

Motor V8 je vysoko výkonný runtime modul pre zostavovanie webov s otvoreným zdrojovým kódom pre JavaScript, ktorý je napísaný v jazyku C ++ od spoločnosti Google. Väčšina prehliadačov spúšťa skript JavaScript pomocou nástroja V8 a používa ho aj populárne uzlové prostredie runtime.

V jednoduchej angličtine je program V8 programom C ++, ktorý prijíma kód JavaScript, kompiluje ho a vykonáva.

V8 robí dve hlavné veci;

  • Vyhradenie pamäte haldy
  • Kontext vykonávania zásobníka

Naše podozrenie bolo smutné. V8 má iba jeden zásobník hovorov, zásobník hovorov považujte za vlákno.

Jedno vlákno === jeden zásobník hovorov === jedno vykonanie naraz.

Obrázok – Hacker Poludnie

Pretože V8 má iba jeden zásobník hovorov, ako potom JavaScript bežia súbežne a asynchrónne bez blokovania hlavného vlákna vykonávania?

Pokúsme sa to zistiť napísaním jednoduchého, ale bežného asynchrónneho kódu a jeho analýzou.

JavaScript spúšťa každý kód riadok po riadku, jeden po druhom (jednovláknový). Ako sa očakávalo, prvý riadok sa vytlačí tu na konzole, ale prečo sa posledný riadok vytlačí pred vypršaním časového limitu? Prečo proces vykonávania nečaká na vypršanie časového limitu (blokovanie) a potom sa spustí posledný riadok?

Zdá sa, že nám niektoré ďalšie vlákno pomohlo vykonať tento časový limit, pretože sme si celkom istí, že vlákno dokáže kedykoľvek vykonať iba jednu úlohu..

Poďme sa nazerať do Zdrojový kód V8 na chvíľu.

Počkaj čo??!!! Vo V8 nie sú žiadne funkcie časovača, nie DOM? Žiadne udalosti? Nie AJAX?…. Yeeeeessss!!!

Udalosti, DOM, časovače atď. Nie sú súčasťou základnej implementácie JavaScriptu. JavaScript je prísne v súlade so špecifikáciami skriptov Ecma a jeho rôzne verzie sa často označujú podľa špecifikácií skriptov Ecma (ES X)..

Vykonávací workflow

Udalosti, časovače, požiadavky Ajaxu sú poskytované na strane klienta v prehľadávačoch a často sa nazývajú Web API. Sú to tie, ktoré umožňujú jednovláknovému JavaScriptu neblokovať, súbežne a asynchrónne! Ale ako?

Existujú tri hlavné oddiely pracovného postupu vykonávania ľubovoľného programu JavaScript, zásobníka hovorov, webového rozhrania API a frontu úloh..

Zásobník hovorov

Stoh je dátová štruktúra, v ktorej posledný pridaný prvok je vždy prvý, ktorý sa má zo stohu odstrániť. Môžete ho považovať za stoh platne, z ktorého je možné najskôr odstrániť iba prvú platňu, ktorá bola naposledy pridaná. Zásobník hovorov nie je nič iné ako štruktúra údajov zásobníka, v ktorej sa podľa toho vykonávajú úlohy alebo kód.

Pozrime sa na nasledujúci príklad;

Zdroj – https://youtu.be/8aGhZQkoFbQ

Keď zavoláte funkciu printSquare (), vloží sa do zásobníka hovorov, funkcia printSquare () zavolá funkciu square (). Štvorcová funkcia () sa nasunie na zásobník a zavolá aj funkciu násobenia (). Funkcia násobenia sa nasunie na stoh. Pretože funkcia násobenia sa vracia a je poslednou vecou, ​​ktorá bola poslaná do zásobníka, je jej prvá vyriešená a je odstránená zo zásobníka, nasledovaná funkciou square () a potom funkciou printSquare ()..

Webové rozhranie API

To je miesto, kde sa kód, ktorý nespracováva motor V8, vykonáva tak, aby „blokoval“ hlavné vlákno vykonávania. Keď zásobník hovorov narazí na funkciu webového rozhrania API, proces sa okamžite odovzdá do rozhrania Web API, kde sa vykonáva, a uvoľnenie zásobníka na vykonávanie ďalších operácií počas jeho vykonávania.

Vráťme sa k nášmu príkladu setTimeout vyššie;

Keď spustíme kód, prvý riadok konzoly.log sa dostane do zásobníka a výstup dostaneme takmer okamžite, po dosiahnutí časového limitu sú časovače ovládané prehliadačom a nie sú súčasťou základnej implementácie V8, sú tlačené do webového rozhrania API namiesto toho uvoľnenie zásobníka, aby mohol vykonávať ďalšie operácie.

Kým časový limit stále beží, zásobník prejde na ďalší riadok akcie a spustí poslednú konzolu.log, čo vysvetľuje, prečo dostávame tento výstup pred výstupom časovača. Po dokončení časovača sa niečo stane. V konzole hovorov sa znova objaví súbor console.log, potom časovač!

ako?

Cyklus udalostí

Predtým, ako budeme diskutovať o cykle udalostí, najprv prejdeme funkciou frontu úloh.

Vráťme sa k nášmu príkladu časového limitu, keď webové rozhranie API dokončí vykonávanie úlohy, ale automaticky ho neposunie späť späť do zásobníka hovorov. Ide to do Fronta úloh. 

Fronta je dátová štruktúra, ktorá pracuje na princípe First in First out, takže keď sa úlohy dostanú do frontu, dostanú sa v rovnakom poradí. Úlohy, ktoré vykonali webové rozhrania API a ktoré sa tlačia do frontu úloh, sa potom vrátia späť do zásobníka hovorov a vytlačia sa ich výsledky..

Ale počkaj. ČO JE HOKEJ AKÉKOĽVKO LOOP???

Zdroj – https://youtu.be/8aGhZQkoFbQ

Slučka udalostí je proces, ktorý čaká na vymazanie zásobníka, predtým, ako posunie spätné volania z frontu úloh do zásobníka hovorov. Akonáhle je zásobník prázdny, cyklus udalostí spustí a skontroluje dostupné spätné volania vo fronte úloh. Ak nejaké existujú, tlačí ich do zásobníka hovorov, čaká, kým sa zásobník hovorov opäť nevyprázdni, a zopakuje rovnaký postup..

Zdroj – https://www.quora.com/How-does-an-event-loop-work/answer/Timothy-Maxwell

Vyššie uvedený diagram znázorňuje základný pracovný tok medzi cyklom udalostí a frontom úloh.

záver

Aj keď je to veľmi jednoduchý úvod, koncept asynchrónneho programovania v JavaScripte poskytuje dostatočný prehľad na jasné pochopenie toho, čo sa deje pod kapotou a ako je JavaScript schopný bežať súbežne a asynchrónne s jediným vláknom..

JavaScript je vždy na požiadanie, a ak ste zvedaví, odporúčame vám pozrieť si ho Kurz Udemy.

Jeffrey Wilson Administrator
Sorry! The Author has not filled his profile.
follow me
    Like this post? Please share to your friends:
    Adblock
    detector
    map