Hvordan fungerer Event Loop i JavaScript?

Selvom det muligvis kræver en dybdegående forståelse af sprog som C ++ og C for at skrive produktionskode i fuld skala, kan JavaScript ofte skrives med bare en grundlæggende forståelse af, hvad der kan gøres med sproget.


Begreber, som at videregive tilbagekald til funktioner eller skrive asynkron kode, er ofte ikke så vanskelige at implementere, hvilket får de fleste JavaScript-udviklere til at bekymre sig mindre om, hvad der foregår under hætten. De er bare ligeglad med at forstå de kompleksiteter, der er dybt abstraheret fra dem af sproget.

Som JavaScript-udvikler bliver det stadig vigtigere at forstå, hvad der virkelig sker under hætten, og hvordan de fleste af disse kompleksiteter, der er abstraheret fra os, virkelig fungerer. Det hjælper os med at tage mere informerede beslutninger, som igen kan øge vores kodeydelse drastisk.

Denne artikel fokuserer på et af de meget vigtige, men sjældent forståede begreber eller udtryk i JavaScript. Det BEGIVENHEDSLØB!. 

At skrive asynkron kode kan ikke undgås i JavaScript, men hvorfor betyder en kode, der kører asynkron, virkelig? dvs.. Event Loop

Inden vi kan forstå, hvordan begivenhedsløkken fungerer, skal vi først forstå, hvad JavaScript er, og hvordan det fungerer!

Hvad er JavaScript?

Inden vi fortsætter, vil jeg gerne have, at vi tager et skridt tilbage til det grundlæggende. Hvad er egentlig JavaScript? Vi kunne definere JavaScript som;

JavaScript er et højt niveau, fortolket, enkelt trådet ikke-blokerende, asynkront, samtidigt sprog.

Vent, hvad er det her? En boglig definition? ��

Lad os nedbryde det!

Nøgleordene her for så vidt angår denne artikel er single-threaded, ikke-blokerende, samtidigt, og asynkron.

Enkelt tråd

En tråd til udførelse er den mindste sekvens af programmeret instruktion, der kan styres uafhængigt af en scheduler. Et programmeringssprog er enkelttrådede, det betyder, at det kun kan udføre en opgave eller handling på en gang. Dette betyder, at det vil udføre en hel proces fra start til slut, uden at tråden afbrydes eller stoppes.

I modsætning til multetrådede sprog, hvor flere processer kan køres på flere tråde samtidigt uden at blokere hinanden.

Hvordan kan JavaScript være single-threaded og ikke-blokerende på samme tid?

Men hvad betyder blokering?

Ikke-blokerende

Der er ingen definition af blokering; det betyder bare ting, der kører langsomt på tråden. Så ikke-blokering betyder ting, der ikke er langsomt på tråden.

Men vent, sagde jeg, at JavaScript kører på en enkelt tråd? Og jeg sagde også, at det ikke blokerede, hvilket betyder, at opgaven køres hurtigt på opkaldsstakken? Men hvordan??? Hvad med, når vi kører timere? sløjfer?

Slap af! Vi finder ud af det lidt ��.

Samtidig

Samtidig betyder, at koden udføres samtidigt med mere end en tråd.

Okay, tingene bliver virkelig mærkelig nu, hvordan kan JavaScript være single-threaded og være samtidigt på samme tid? dvs. at udføre sin kode med mere end en tråd?

Asynkron

Asynkron programmering betyder, at koden kører i en begivenhedssløjfe. Når der er en blokerende handling, startes begivenheden. Blokeringskoden kører fortsat uden at blokere hovedudførelsestråden. Når blokeringskoden er færdig med at køre, er den køen resultatet af blokeringsoperationerne og skubber dem tilbage til stakken.

Men JavaScript har en enkelt tråd? Hvad udfører derefter denne blokkeringskode, mens andre koder i tråden udføres?

Inden vi fortsætter, lad os se en oversigt over ovenstående.

  • JavaScript er enkeltrådet
  • JavaScript blokerer ikke, dvs. langsomme processer blokerer ikke for dens udførelse
  • JavaScript er samtidigt, dvs. det udfører sin kode i mere end en tråd på samme tid
  • JavaScript er asynkron, dvs. det kører blokeringskode et andet sted.

Men ovenstående tilføjer ikke nøjagtigt, hvordan kan et enkelt-trådet sprog være ikke-blokerende, samtidigt og asynkront?

Lad os gå lidt dybere, lad os gå ned til JavaScript-runtime-motorer, V8, måske har den nogle skjulte tråde, vi ikke er opmærksomme på.

V8-motor

V8-motoren er en højtydende, open source webmontering runtime-motor til JavaScript skrevet i C ++ af Google. De fleste browsere kører JavaScript ved hjælp af V8-motoren, og selv det populære knudepunkt js runtime-miljø bruger det også.

På enkel engelsk er V8 et C ++ -program, der modtager JavaScript-kode, kompilerer og udfører det.

V8 gør to vigtige ting;

  • Hukommelsestildeling
  • Kontekstudførelse kontekst

Desværre var vores mistanke forkert. V8 har kun en opkaldsstabel, tænk på opkaldsstakken som tråden.

Én tråd === en opkaldsstabel === en udførelse ad gangen.

Billede – Hacker middag

Da V8 kun har en opkaldsstabel, hvordan kører JavaScript derefter samtidigt og asynkront uden at blokere hovedudførelsestråden?

Lad os prøve at finde ud af det ved at skrive en enkel, men alligevel almindelig asynkron kode og analysere den sammen.

JavaScript kører hver kode linje for linje, en efter hinanden (enkelt-gevind). Som forventet udskrives den første linje i konsollen her, men hvorfor udskrives den sidste linje før timeoutkoden? Hvorfor venter ikke eksekveringsprocessen på timeoutkoden (blokering), før den går videre til at køre den sidste linje?

Nogle andre tråde synes at have hjulpet os med at udføre denne timeout, da vi er temmelig sikre på, at en tråd kun kan udføre en enkelt opgave på ethvert tidspunkt..

Lad os tage et smugkig ind i V8 Kildekode i et stykke tid.

Vent, hvad??!!! Der er ingen timerfunktioner i V8, ingen DOM? Ingen begivenheder? Ingen AJAX?…. Yeeeeessss!!!

Begivenheder, DOM, timere osv. Er ikke en del af JavaScript’s centrale implementering, JavaScript er i nøje overensstemmelse med Ecma Scripts specifikationer, og forskellige versioner af det henvises ofte til i henhold til dets Ecma Scripts specifikationer (ES X).

Udførelsesarbejdsgang

Begivenheder, timere, Ajax-anmodninger leveres alle på klientsiden af ​​browserne og kaldes ofte Web API. Det er dem, der tillader, at den enkelttrådede JavaScript er ikke-blokerende, samtidig og asynkron! Men hvordan?

Der er tre hovedafsnit i udførelsesarbejdsprocessen for ethvert JavaScript-program, opkaldsstakken, web-API’en og opgavekøen.

Opkaldsstakken

En stak er en datastruktur, hvor det sidste element, der blev tilføjet, altid er det første, der fjernes fra stakken. Man kunne tænke på det som en stabel af en plade, hvor kun den første plade, der var den sidst tilføjede, først kan fjernes. En opkaldsstabel er simpelthen kun andet end en stakdatastruktur, hvor opgaver eller kode udføres i overensstemmelse hermed.

Lad os se på nedenstående eksempel;

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

Når du kalder funktionen printSquare (), skubbes den ind på opkaldsstakken, funktionen printSquare () kalder funktionen firkant (). Funktionen firkant () skubbes på stakken og kalder også multiplikation () -funktionen. Multiplikationsfunktionen skubbes ind på stakken. Da multiplikationsfunktionen vender tilbage og er den sidste ting, der blev skubbet til stakken, løses dens først og fjernes fra stakken, efterfulgt af funktionen firkant () og derefter funktionen printSquare ().

Web API

Det er her kode, der ikke håndteres af V8-motoren, udføres for ikke at “blokere” hovedudførelsestråden. Når Call Stack støder på en web API-funktion, overdrages processen straks til Web API, hvor den udføres og frigør Call Stack til at udføre andre operationer under dens udførelse.

Lad os gå tilbage til vores setTimeout-eksempel ovenfor;

Når vi kører koden, skubbes den første konsol.log-linje til stakken, og vi får vores output næsten øjeblikkeligt, når vi kommer til timeout, bliver timere håndteret af browseren og er ikke en del af V8s centrale implementering, det bliver skubbet til Web API i stedet for at frigøre stakken, så den kan udføre andre operationer.

Mens timeout stadig kører, går stakken videre til den næste handlingslinje og kører den sidste konsol.log, hvilket forklarer, hvorfor vi får det output før timerudgangen. Når timeren er afsluttet, sker der noget. Console.log i derefter timer vises magisk i opkaldsstakken igen!

Hvordan?

Event Loop

Lad os først gå igennem funktionen af ​​opgavekøen, før vi diskuterer begivenhedsløkken.

Tilbage til vores timeouteksempel, når Web API først er færdig med at udføre opgaven, skubber den ikke blot tilbage til opkaldsstakken automatisk. Det går til Opgave kø. 

En kø er en datastruktur, der fungerer efter First in First out-princippet, så når opgaver bliver skubbet ind i køen, kommer de ud i samme rækkefølge. Opgaver, der er blevet udført af Web API’erne, der skubbes til opgavekøen, og gå derefter tilbage til Opkaldsstakken for at få deres udskrivning udskrevet.

Men vent. HVILKEN ER HENDELSESLOPPEN???

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

Begivenhedssløjfen er en proces, der venter på, at opkaldsstablen skal være klar, inden du skubber tilbagekald fra opgavekøen til opkaldsstablen. Når stakken er klar, udløser og kontrollerer hændelsesløkken opgavekøen for tilgængelige tilbagekald. Hvis der er nogen, skubbes den til opkaldsstablen, venter på, at opkaldsstablen er klar igen og gentager den samme proces.

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

Ovenstående diagram viser den grundlæggende arbejdsgang mellem Event Loop og Task Queue.

Konklusion

Selvom dette er en meget grundlæggende introduktion, giver konceptet med asynkron programmering i JavaScript tilstrækkelig indsigt til klart at forstå, hvad der foregår under hætten, og hvordan JavaScript er i stand til at køre samtidigt og asynkron med bare en enkelt tråd.

JavaScript er altid on-demand, og hvis du er nysgerrig efter at lære, vil jeg råde dig til at tjekke dette Udemy kursus.

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