JavaScripti samaaegsusmudel ja sündmuste ring

Javascripti käitusaeg on ühe keermega, mis tähendab, et see saab korraga käivitada ühe koodiosa. Samaväärsusmudeli ja Javascripti sündmussilmu mõistmiseks peame kõigepealt tundma õppima mõnda sellega seotud levinud terminit.

Kõnepinu

Kõigepealt uurime, mis on kõnepakk.

Kõnepinu on lihtne andmestruktuur, mis salvestab, kus koodis me praegu asume. Nii et kui astume funktsiooni, mis on funktsiooni kutsumine, lükatakse see kõnepinu. Funktsioonilt naastes hüpatakse see virnast välja.

Kõnepinu mõistmiseks vaatame koodi näidet:

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);

Esiteks, kui kood käivitab, loeb käitamise aeg kõik funktsioonide definitsioonid läbi. Kuid kui see jõuab reale, kus kutsutakse esimest funktsiooni printSquare (5), lükkab see selle funktsiooni kõnepinu.

Järgmisena käivitatakse see funktsioon. Enne tagasipöördumist kohtab see teist funktsiooni, ruudus (n) , nii et see peatab oma praeguse toimimise ja surub selle funktsiooni olemasoleva funktsiooni peale.

See täidab funktsiooni (antud juhul ruudukujulise funktsiooni) ja lõpuks kohtab teist funktsiooni korrutamist (n, n) . Seejärel peatab ta oma praegused hukkamised ja lükkab selle funktsiooni kõnepinu. Funktsioon korrutab täidab ja naaseb korrutatud väärtusega.

Lõpuks naaseb ruutu funktsioon ja see hüpatakse virnast välja ning sama kehtib ka printSquare'iga. Lõplik ruutväärtus omistatakse muutujale numberSquared.

Taas kohtame funktsiooni kutsumist (antud juhul on see lause console.log ()), nii et käituse aeg lükkab selle virna. See täidab selle, printides seega konsoolile ruudu numbri.

Pange tähele, et esimene funktsioon, mis enne mis tahes ülaltoodud koodi käivitamist virna lükatakse, on peamine funktsioon. Käitusajal tähistatakse seda kui "anonüümset funktsiooni".

Nii et kokkuvõtteks: kui funktsioon käivitatakse, lükatakse see kõnepinu, kus see käivitub. Lõpuks, kui funktsioon on selle täitmisega lõpetatud ja kas kaudselt või selgesõnaliselt naaseb, hüpatakse see virnast välja.

Kõnepinu lihtsalt salvestab, millisel ajahetkel funktsiooni käivitati. Ja see jälgib, millist funktsiooni praegu täidetakse.

Brauser

Nüüd teame sellest, et Javascript saab käivitada ühe asja korraga, kuid brauseri puhul see nii ei ole. Brauseril on oma komplekt API-sid, nagu setTimeout ja XMLHttpRequests, mida pole JavaScripti käituse ajal määratud.

Tegelikult, kui vaatate V8 lähtekoodi, mis on populaarne Javascripti käitusaeg, mis toidab brausereid nagu Google Chrome, ei leia te sellele mingeid määratlusi. Seda seetõttu, et need spetsiaalsed veebi-API-d eksisteerivad brauserikeskkonnas, mitte javascripti keskkonnas. Nii et võite öelda, et need API-d lisavad segusse samaaegsust.

Vaatame kogu pildi mõistmiseks skeemi.

Samaaegsus ja sündmuse tsükli mudel

Siin on veel mõned terminid, nii et lähme neist läbi:

Hunnik : see on enamasti koht, kuhu objektid eraldatakse.

Tagasihelistamise järjekord : see on andmestruktuur, mis salvestab kõik tagasihelistamised. Kuna see on järjekord, töödeldakse elemente FIFO põhjal, mis on First in First Out.

Event Loop : Siin saavad kõik need asjad kokku. Sündmuse silmus kontrollib lihtsalt kõnepinu ja kui see on tühi (see tähendab, et korstnas pole ühtegi funktsiooni), võtab see tagasihelistusjärjekorrast vanima tagasihelistamise ja lükkab selle kõnepinu, mis lõpuks tagasihelistamise täidab.

Mõistame seda koodinäite abil:

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

Esimese rea käivitamisel on see console.log (). See on funktsiooni kutsumine, mis tähendab, et see funktsioon lükatakse kõnepinu, kus see printib konsoolile "hi". Lõpuks see tagastatakse ja hüpatakse virnast välja.

Siis, kui käitusaeg läheb setTimeout () käivitama, teab ta, et see on veebi API. Seetõttu annab see selle brauserile ülesandeks. Brauser käivitab taimeri ja seejärel hüppab JS runtime setTimeout () virnast välja. See kohtub järjekordse konsooli.log () kutsega ja nii lükatakse see kõnepinu, teade 'JS' logitakse konsooli ja siis see lõpuks tagastatakse. Seejärel hüpatakse virnast välja viimane console.log (). Nüüd on kõnepinu tühi.

Vahepeal, kuni see kõik kestis, sai taimer valmis. Kui 5 sekundit on möödunud, läheb brauser edasi ja lükkab tagasihelistamisfunktsiooni tagasihelistusjärjekorda.

Järgmisena kontrollib sündmuse silmus, kas kõnepinu on vaba või mitte. Kuna see on tasuta, võtab see tagasihelistamisfunktsiooni ja lükkab selle uuesti tagasi kõnekogumisse, mis käivitab selle sees oleva koodi.

Jällegi on koodi sees konsooli.log () kutsumine, nii et see funktsioon läheb virna ülaossa, mis logib konsooli "freecodecamp" ja lõpuks naaseb. See tähendab, et see hüppab virnast välja ja lõpuks hüpatakse tagasi tagasi ja oleme valmis.

Selle paremaks visualiseerimiseks proovige seda tööriista, autor: Phillip Roberts: Loupe Event Loop Visualizer