„JavaScript“ vykdymo modelis yra niuansuotas ir lengvai nesuprantamas. Gali padėti sužinoti apie įvykio ciklo esmę.

„JavaScript“ yra vienos gijos kalba, sukurta užduotims atlikti po vieną. Tačiau įvykių ciklas leidžia „JavaScript“ tvarkyti įvykius ir atgalinius skambučius asinchroniškai, emuliuojant vienalaikes programavimo sistemas. Tai užtikrina jūsų „JavaScript“ programų našumą.

Kas yra „JavaScript“ įvykių ciklas?

„JavaScript“ įvykių ciklas yra mechanizmas, veikiantis kiekvienos „JavaScript“ programos fone. Tai leidžia JavaScript tvarkyti užduotis nuosekliai, neužblokuojant pagrindinės vykdymo gijos. Tai vadinama asinchroninis programavimas.

Įvykio ciklas išlaiko eilę užduočių, kurias reikia vykdyti, ir pateikia šias užduotis į dešinę žiniatinklio API vykdymui po vieną. JavaScript seka šias užduotis ir tvarko kiekvieną pagal užduoties sudėtingumo lygį.

Suprasti JavaScript įvykių ciklo ir asinchroninio programavimo poreikį. Turite suprasti, kokią problemą ji iš esmės išsprendžia.

Paimkite šį kodą, pavyzdžiui:

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

Šis kodas pirmiausia apibrėžia funkciją, vadinamą LongRunningFunction(). Ši funkcija atliks tam tikrą sudėtingą, daug laiko reikalaujančią užduotį. Šiuo atveju jis atlieka a dėl ciklas kartojasi daugiau nei 100 000 kartų. Tai reiškia, kad console.log ("Sveiki") veikia 100 000 kartų.

Priklausomai nuo kompiuterio greičio, tai gali užtrukti ilgai ir užblokuoti shortRunningFunction() nuo tiesioginio vykdymo iki ankstesnės funkcijos užbaigimo.

Kontekstui čia pateikiamas abiejų funkcijų vykdymo laiko palyginimas:

Ir tada singlas shortRunningFunction():

Skirtumas tarp 2 351 milisekundės operacijos ir 0 milisekundės operacijos yra akivaizdus, ​​kai siekiate sukurti našią programą.

Kaip įvykių ciklas padeda pagerinti programos našumą

Įvykio ciklas turi skirtingus etapus ir dalis, kurios prisideda prie sistemos veikimo.

Skambučių krūva

„JavaScript“ iškvietimų krūva yra būtina norint, kaip „JavaScript“ tvarko funkcijų ir įvykių iškvietimus iš jūsų programos. JavaScript kodas kompiliuojamas iš viršaus į apačią. Tačiau Node.js, nuskaitęs kodą, priskirs funkcijų iškvietimus iš apačios į viršų. Skaitydamas jis po vieną perkelia apibrėžtas funkcijas kaip kadrus į skambučių krūvą.

Skambučių krūva yra atsakinga už vykdymo konteksto ir teisingos funkcijų tvarkos palaikymą. Jis tai daro veikdamas kaip „Paskutinis pirmas-išeinantis“ (LIFO) kaminas.

Tai reiškia, kad paskutinis funkcijos kadras, kurį jūsų programa įstumia į skambučių krūvą, bus pirmasis, kuris iššoks iš krūvos ir paleis. Tai užtikrins, kad „JavaScript“ išlaikys tinkamą funkcijų vykdymo tvarką.

„JavaScript“ iškels kiekvieną kadrą iš krūvos, kol jis bus tuščias, tai reiškia, kad visos funkcijos bus baigtos veikti.

Libuv Web API

„JavaScript“ asinchroninių programų esmė yra libuv. Libuv biblioteka parašyta C programavimo kalba, kuri gali sąveikauti su operacine sistema žemo lygio API. Bibliotekoje bus keletas API, leidžiančių „JavaScript“ kodui veikti lygiagrečiai su kitais kodas. API gijų kūrimui, API ryšiui tarp gijų ir API gijų sinchronizavimui valdyti.

Pavyzdžiui, kai naudojate setTimeout faile Node.js, kad sustabdytumėte vykdymą. Laikmatis nustatomas per „libuv“, kuris valdo įvykio kilpą, kad atliktų atgalinio skambučio funkciją, kai praeis nurodyta delsa.

Panašiai, kai tinklo operacijas atliekate asinchroniškai, „Libuv“ atlieka tas operacijas neblokuojančiai. būdu, užtikrinant, kad kitos užduotys galėtų tęsti apdorojimą nelaukiant, kol bus atlikta įvesties/išvesties (I/O) operacija galas.

Atgalinio skambinimo ir įvykių eilė

Atgalinio skambinimo ir įvykių eilė yra ta vieta, kur atgalinio skambinimo funkcijos laukia vykdymo. Kai asinchroninė operacija baigiama iš libuvo, atitinkama atgalinio skambinimo funkcija įtraukiama į šią eilę.

Štai kaip vyksta seka:

  1. „JavaScript“ perkelia asinchronines užduotis į „Libuv“, kad ji galėtų tvarkyti, ir nedelsdama toliau tvarko kitą užduotį.
  2. Kai asinchroninė užduotis baigiama, „JavaScript“ prideda atgalinio skambinimo funkciją į atgalinio skambinimo eilę.
  3. „JavaScript“ toliau vykdo kitas užduotis iškvietimo krūvoje, kol bus atlikta viskas pagal esamą tvarką.
  4. Kai skambučių krūva tuščia, „JavaScript“ peržiūri atgalinio skambinimo eilę.
  5. Jei eilėje yra atgalinis skambutis, pirmasis perkeliamas į skambučių krūvą ir jį vykdo.

Tokiu būdu asinchroninės užduotys neužblokuoja pagrindinės gijos, o atgalinio skambinimo eilė užtikrina, kad atitinkami jų atgaliniai iškvietimai būtų vykdomi tokia tvarka, kokia buvo užbaigtos.

Įvykio ciklo ciklas

Įvykio ciklas taip pat turi kažką vadinamo mikroužduočių eilute. Šioje specialioje įvykių ciklo eilėje yra mikroužduotys, suplanuotos vykdyti, kai tik bus baigta esama užduotis skambučių krūvoje. Šis vykdymas įvyksta prieš kitą atvaizdavimą arba įvykio ciklo iteraciją. Mikroužduotys yra didelio prioriteto užduotys, turinčios pirmenybę prieš įprastas užduotis įvykių cikle.

Mikroužduotys dažniausiai sukuriamos dirbant su Promises. Kai pažadas išsprendžiamas arba atmetamas, jis atitinka .tada () arba .catch() atgaliniai skambučiai prisijungia prie mikroužduočių eilės. Galite naudoti šią eilę tvarkydami užduotis, kurias reikia nedelsiant vykdyti po dabartinės operacijos, pvz., atnaujinti programos vartotojo sąsają arba tvarkyti būsenos pakeitimus.

Pavyzdžiui, žiniatinklio programa, kuri atlieka duomenų gavimą ir atnaujina vartotojo sąsają pagal gautus duomenis. Vartotojai gali suaktyvinti šį duomenų gavimą pakartotinai spustelėdami mygtuką. Kiekvienas mygtuko paspaudimas inicijuoja asinchroninę duomenų gavimo operaciją.

Be mikroužduočių šios užduoties įvykių ciklas veiktų taip:

  1. Vartotojas kelis kartus spusteli mygtuką.
  2. Kiekvienas mygtuko paspaudimas suaktyvina asinchroninę duomenų gavimo operaciją.
  3. Baigus duomenų gavimo operacijas, „JavaScript“ prideda atitinkamus atgalinius skambučius į įprastą užduočių eilę.
  4. Įvykio ciklas pradeda apdoroti užduotis įprastoje užduočių eilėje.
  5. UI naujinimas, pagrįstas duomenų gavimo rezultatais, vykdomas, kai tik tai leidžia įprastos užduotys.

Tačiau naudojant mikroužduotį įvykių ciklas veikia kitaip:

  1. Vartotojas pakartotinai spusteli mygtuką ir suaktyvina asinchroninę duomenų gavimo operaciją.
  2. Kai duomenų gavimo operacijos baigtos, įvykių ciklas įtraukia atitinkamus atgalinius skambučius į mikroužduočių eilę.
  3. Įvykio ciklas pradeda apdoroti užduotis mikroužduočių eilėje iškart po to, kai baigia esamą užduotį (mygtuko paspaudimas).
  4. NS naujinimas, pagrįstas duomenų gavimo rezultatais, vykdomas prieš kitą įprastą užduotį, todėl naudotojas reaguoja geriau.

Štai kodo pavyzdys:

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

Šiame pavyzdyje kiekvienas mygtuko „Pateikti“ paspaudimas iškviečia gautiduomenys (). Kiekvienas duomenų gavimo operacijų grafikas yra mikroužduotys. Remiantis gautais duomenimis, vartotojo sąsajos naujinimas vykdomas iškart po kiekvienos gavimo operacijos pabaigos, prieš atliekant bet kokias kitas atvaizdavimo ar įvykių ciklo užduotis.

Taip užtikrinama, kad vartotojai matytų atnaujintus duomenis be jokių vėlavimų dėl kitų įvykio ciklo užduočių.

Naudojant mikroužduotis tokiuose scenarijuose kaip šis gali užkirsti kelią vartotojo sąsajos perkėlimui ir užtikrinti greitesnę bei sklandesnę programos sąveiką.

Įvykių ciklo reikšmė žiniatinklio kūrimui

Norint sukurti našias ir reaguojančias programas, labai svarbu suprasti įvykių kilpą ir kaip naudotis jos funkcijomis. Įvykių ciklas suteikia asinchronines ir lygiagrečias galimybes, todėl galite efektyviai atlikti sudėtingas užduotis savo programoje nepakenkdami vartotojo patirčiai.

Node.js suteikia viską, ko jums reikia, įskaitant žiniatinklio darbuotojus, kad būtų pasiektas tolesnis lygiagretumas už pagrindinės „JavaScript“ gijos.