JavaScript-samtidighedsmodel og hændelsessløjfe

Javascript-kørselstid er enkeltgevind, hvilket betyder, at den kan udføre et stykke kode ad gangen. For at forstå samtidighedsmodellen og hændelsesløkken i Javascript skal vi først kende nogle almindelige udtryk, der er knyttet til den.

Opkaldsstakken

Lad os først lære om, hvad en opkaldsstak er.

En opkaldstak er en simpel datastruktur, der registrerer, hvor i koden vi er i øjeblikket. Så hvis vi træder ind i en funktion, der er en funktionsopkald, skubbes den til opkaldsstakken. Når vi vender tilbage fra en funktion, poppes den ud af stakken.

Lad os se på et kodeeksempel for at forstå opkaldstakken:

function multiply(x,y) { return x * y; } function squared(n) { return multiply(n,n) } function printSquare(n) { return squared(n) } let numberSquared = printSquare(5); console.log(numberSquared);

Først når koden udføres, vil runtime læse igennem hver af funktionsdefinitionerne. Men når den når linjen, hvor den første funktion printSquare (5) påberåbes, vil den skubbe denne funktion ind i opkaldstakken.

Dernæst udføres denne funktion. Før den vender tilbage, vil den støde på en anden funktion, kvadratisk (n) , så den vil suspendere den aktuelle operation og skubbe denne funktion oven på den eksisterende funktion.

Den udfører funktionen (i dette tilfælde den kvadrerede funktion) og til sidst støder den på en anden funktion ganget (n, n) . Derefter suspenderer den sine nuværende henrettelser og skubber denne funktion ind i opkaldstakken. Funktionen multiplik udføres, og den vender tilbage med den gangede værdi.

Endelig vender den kvadrerede funktion tilbage og poppes fra stakken, og det samme gælder for printSquare. Den endelige kvadratiske værdi tildeles variablen numberSquared.

Vi støder igen på en funktionsopkald (i dette tilfælde er det en console.log () -erklæring), så runtime skubber dette til stakken. Dette udfører det og udskriver det kvadratiske nummer på konsollen.

Bemærk, at den første funktion, der bliver skubbet ind i stakken, før en af ​​ovenstående koder kører, er hovedfunktionen. I løbetiden betegnes dette som en 'anonym funktion'.

Så for at opsummere: hver gang en funktion påberåbes, skubbes den ind i opkaldstakken, hvor den udføres. Endelig når funktionen er færdig med dens udførelse og returnerer enten implicit eller eksplicit, vil den blive poppet ud af stakken.

Opkaldsstakken registrerer bare på hvilket tidspunkt, hvilken funktion der blev udført. Og det holder styr på, hvilken funktion der i øjeblikket udføres.

Browseren

Nu ved vi ud fra dette, at Javascript kan udføre en ting ad gangen, men det er ikke tilfældet med browseren. Browseren har sit eget sæt API'er som setTimeout og XMLHttpRequests, som ikke er specificeret i Javascript-runtime.

Faktisk hvis du kigger igennem kildekoden til V8, den populære Javascript-runtime, der driver browsere som Google Chrome, finder du ingen definitioner til det. Det skyldes, at disse specielle web-API'er findes i browsermiljøet ikke i javascript-miljøet. Så du kan sige, at disse API'er introducerer samtidighed i blandingen.

Lad os se på et diagram for at forstå hele billedet.

Samtidig model og begivenhedsløjfemodel

Nogle flere vilkår introduceres her, så lad os gennemgå dem:

Heap : Det er for det meste stedet, hvor objekter tildeles.

Callback-kø : Det er en datastruktur, der gemmer alle tilbagekald. Da det er en kø, behandles elementerne baseret på FIFO, som er First in First Out.

Event Loop : Det er her alle disse ting kommer sammen. Begivenhedssløjfen kontrollerer simpelthen opkaldstakken, og hvis den er tom (hvilket betyder, at der ikke er nogen funktioner i stakken), tager den den ældste tilbagekald fra tilbagekaldskøen og skubber den ind i opkaldstakken, som til sidst udfører tilbagekaldet.

Lad os forstå dette med et kodeeksempel:

console.log('hi'); setTimeout(function() { console.log('freecodeCamp') },5000); console.log('JS')

Når den første linje udføres, er det en console.log (). Dette er en funktionsopkald, der betyder, at denne funktion skubbes ind i opkaldstakken, hvor den udskriver 'hi' til konsollen. Endelig returneres den og poppes fra stakken.

Derefter når runtime går til at udføre setTimeout () ved det, at dette er en web-API. Derfor giver det det til browseren for at håndtere dets udførelse. Browseren starter timeren, og derefter springer JS runtime setTimeout () ud af stakken. Det støder på en anden konsol.log () påkaldelse, og så skubber den dette ind i opkaldsstakken, meddelelsen 'JS' logges ind i konsollen, og så returneres den endelig. Derefter poppes den sidste console.log () fra stakken. Nu er opkaldstakken tom.

I mellemtiden mens alt dette foregik, slutter timeren. Når der er gået 5 sekunder, fortsætter browseren og skubber tilbagekaldsfunktionen ind i tilbagekaldskøen.

Dernæst kontrollerer begivenhedssløjfen, om opkaldsstakken er gratis eller ikke. Da det er gratis, tager det tilbagekaldsfunktionen og skubber den igen tilbage til opkaldsstakken, der udfører koden inde i den.

Igen inde i koden er der en konsol.log () påkaldelse, så denne funktion går til toppen af ​​stakken, der logger 'freecodecamp' ind i konsollen, og til sidst vender den tilbage. Dette betyder, at det bliver poppet ud af stakken, og til sidst bliver tilbagekaldet poppet ud af stakken, og vi er færdige.

For at visualisere dette bedre, prøv dette værktøj af Phillip Roberts: Loupe Event Loop Visualizer