JavaScript izpildes modelis ir niansēts un viegli pārprotams. Var palīdzēt uzzināt par notikumu cilpu tās pamatā.

JavaScript ir viena pavediena valoda, kas izstrādāta, lai veiktu uzdevumus pa vienam. Tomēr notikumu cilpa ļauj JavaScript apstrādāt notikumus un atzvanus asinhroni, emulējot vienlaicīgas programmēšanas sistēmas. Tas nodrošina jūsu JavaScript lietojumprogrammu veiktspēju.

Kas ir JavaScript notikumu cilpa?

JavaScript notikumu cilpa ir mehānisms, kas darbojas katras JavaScript lietojumprogrammas fonā. Tas ļauj JavaScript apstrādāt uzdevumus secīgi, nebloķējot tā galveno izpildes pavedienu. To dēvē par asinhronā programmēšana.

Notikumu cilpa uztur izpildāmo uzdevumu rindu un padod šos uzdevumus pa labi tīmekļa API izpildei pa vienam. JavaScript seko šiem uzdevumiem un apstrādā katru atbilstoši uzdevuma sarežģītības līmenim.

Izprast JavaScript notikumu cilpas un asinhronās programmēšanas nepieciešamību. Jums ir jāsaprot, kādu problēmu tas būtībā atrisina.

Ņemiet, piemēram, šo kodu:

functionlongRunningFunction() 
instagram viewer
{
// 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 kods vispirms definē funkciju, ko sauc LongRunningFunction(). Šī funkcija veiks kādu sarežģītu un laikietilpīgu uzdevumu. Šajā gadījumā tas veic a priekš cilpa atkārtojas vairāk nekā 100 000 reižu. Tas nozīmē ka console.log ("Sveiki") darbojas 100 000 reižu.

Atkarībā no datora ātruma tas var aizņemt ilgu laiku un bloķēt shortRunningFunction() no tūlītējas izpildes līdz iepriekšējās funkcijas pabeigšanai.

Kontekstam šeit ir abu funkciju izpildei nepieciešamā laika salīdzinājums:

Un tad singls shortRunningFunction():

Atšķirība starp 2351 milisekundes darbību un 0 milisekundes darbību ir acīmredzama, ja vēlaties izveidot veiktspējīgu lietotni.

Kā notikumu cikls palīdz uzlabot lietotnes veiktspēju

Notikumu cilpai ir dažādi posmi un daļas, kas veicina sistēmas darbību.

Zvanu kaudze

JavaScript zvanu steks ir būtisks tam, kā JavaScript apstrādā funkciju un notikumu izsaukumus no jūsu lietojumprogrammas. JavaScript kods tiek apkopots no augšas uz leju. Tomēr Node.js, lasot kodu, Node.js piešķirs funkciju izsaukumus no apakšas uz augšu. Lasīšanas laikā tas pa vienam nospiež definētās funkcijas kā kadrus izsaukuma kaudzē.

Izsaukumu steks ir atbildīgs par izpildes konteksta uzturēšanu un pareizu funkciju secību. Tas tiek darīts, darbojoties kā LIFO (Last-In-First-Out) steks.

Tas nozīmē, ka pēdējais funkciju rāmis, ko jūsu programma nospiež uz izsaukuma steku, būs pirmais, kas tiks noņemts no steka un tiks palaists. Tas nodrošinās, ka JavaScript uztur pareizo funkciju izpildes secību.

JavaScript katru kadru izņems no kaudzes, līdz tas būs tukšs, kas nozīmē, ka visas funkcijas ir beigušās.

Libuv Web API

JavaScript asinhrono programmu pamatā ir libuv. Libuv bibliotēka ir uzrakstīta C programmēšanas valodā, kas var mijiedarboties ar operētājsistēmu zema līmeņa API. Bibliotēka nodrošinās vairākas API, kas ļauj JavaScript kodam darboties paralēli citiem kodu. API pavedienu izveidei, API saziņai starp pavedieniem un API pavedienu sinhronizācijas pārvaldībai.

Piemēram, kad lietojat setTimeout failā Node.js, lai apturētu izpildi. Taimeris tiek iestatīts, izmantojot libuv, kas pārvalda notikumu cilpu, lai izpildītu atzvanīšanas funkciju, kad ir pagājis norādītā aizkave.

Tāpat, veicot tīkla darbības asinhroni, libuv apstrādā šīs darbības nebloķējošā režīmā. veidā, nodrošinot, ka citi uzdevumi var turpināt apstrādi, negaidot ievades/izvades (I/O) darbību beigas.

Atzvanīšanas un notikumu rinda

Atzvanīšanas un notikumu rinda ir vieta, kur atzvanīšanas funkcijas gaida izpildi. Kad asinhronā darbība no libuv tiek pabeigta, tai atbilstošā atzvanīšanas funkcija tiek pievienota šai rindai.

Lūk, kā notiek secība:

  1. JavaScript pārvieto asinhronos uzdevumus uz libuv, lai tas varētu rīkoties, un nekavējoties turpina rīkoties ar nākamo uzdevumu.
  2. Kad asinhronais uzdevums ir pabeigts, JavaScript pievieno savu atzvanīšanas funkciju atzvanīšanas rindai.
  3. JavaScript turpina izpildīt citus zvanu kaudzē esošos uzdevumus, līdz tiek paveikts viss pašreizējā secībā.
  4. Kad zvanu steks ir tukšs, JavaScript apskata atzvanīšanas rindu.
  5. Ja rindā ir atzvans, tas nospiež pirmo zvanu steku un izpilda to.

Tādā veidā asinhronie uzdevumi nebloķē galveno pavedienu, un atzvanīšanas rinda nodrošina, ka tiem atbilstošie atzvani tiek izpildīti tādā secībā, kā tie tika pabeigti.

Notikumu cikla cikls

Notikumu cilpai ir arī kaut kas, ko sauc par mikrouzdevumu rindu. Šajā īpašajā notikumu cilpas rindā ir iekļauti mikrouzdevumi, kas ieplānoti izpildei, tiklīdz pašreizējais uzdevums zvanu stekā ir pabeigts. Šī izpilde notiek pirms nākamās renderēšanas vai notikumu cilpas iterācijas. Mikrouzdevumi ir augstas prioritātes uzdevumi, kuriem ir prioritāte pār parastajiem uzdevumiem notikumu ciklā.

Strādājot ar Promises, parasti tiek izveidots mikrouzdevums. Ikreiz, kad solījums tiek atrisināts vai noraidīts, tas atbilst .tad() vai .catch() atzvanīšanas pievienojas mikrouzdevumu rindai. Varat izmantot šo rindu, lai pārvaldītu uzdevumus, kas nekavējoties jāizpilda pēc pašreizējās darbības, piemēram, lietojumprogrammas lietotāja interfeisa atjaunināšana vai stāvokļa izmaiņu apstrāde.

Piemēram, tīmekļa lietojumprogramma, kas veic datu iegūšanu un atjaunina lietotāja saskarni, pamatojoties uz izgūtajiem datiem. Lietotāji var aktivizēt šo datu ielādi, atkārtoti noklikšķinot uz pogas. Katrs pogas klikšķis sāk asinhronu datu izguves darbību.

Bez mikrouzdevumiem šī uzdevuma notikumu cilpa darbotos šādi:

  1. Lietotājs atkārtoti noklikšķina uz pogas.
  2. Katrs pogas klikšķis aktivizē asinhronas datu iegūšanas darbību.
  3. Kad datu iegūšanas darbības ir pabeigtas, JavaScript pievieno atbilstošos atzvanus parastajai uzdevumu rindai.
  4. Notikuma cilpa sāk uzdevumu apstrādi parastajā uzdevumu rindā.
  5. Lietotāja saskarnes atjauninājums, kas balstīts uz datu iegūšanas rezultātiem, tiek izpildīts, tiklīdz to atļauj regulārie uzdevumi.

Tomēr ar mikrouzdevumiem notikumu cilpa darbojas citādi:

  1. Lietotājs atkārtoti noklikšķina uz pogas un aktivizē asinhrono datu iegūšanas darbību.
  2. Kad datu iegūšanas darbības ir pabeigtas, notikumu cilpa pievieno atbilstošos atzvanus mikrouzdevumu rindai.
  3. Notikuma cilpa sāk apstrādāt uzdevumus mikrouzdevumu rindā uzreiz pēc pašreizējā uzdevuma pabeigšanas (pogas klikšķis).
  4. Lietotāja saskarnes atjauninājums, kura pamatā ir datu iegūšanas rezultāti, tiek izpildīts pirms nākamā parastā uzdevuma, nodrošinot atsaucīgāku lietotāja pieredzi.

Šeit ir koda piemērs:

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

Šajā piemērā katrs klikšķis uz pogas Ienest zvana fetchData(). Katrs datu iegūšanas darbības grafiks kā mikrouzdevums. Pamatojoties uz ienestajiem datiem, lietotāja saskarnes atjauninājums tiek izpildīts uzreiz pēc katras izgūšanas darbības pabeigšanas, pirms tiek veikti citi renderēšanas vai notikumu cilpas uzdevumi.

Tas nodrošina, ka lietotāji redz atjauninātos datus bez aizkaves citu notikumu cilpas uzdevumu dēļ.

Mikrouzdevumu izmantošana šādos scenārijos var novērst lietotāja interfeisa pārrāvumu un nodrošināt ātrāku un vienmērīgāku mijiedarbību jūsu lietojumprogrammā.

Notikumu cikla ietekme uz tīmekļa izstrādi

Izpratne par notikumu cilpu un to funkciju izmantošanu ir būtiska, lai izveidotu veiktspējīgas un atsaucīgas lietojumprogrammas. Notikumu cilpa nodrošina asinhronas un paralēlas iespējas, lai jūs varētu efektīvi apstrādāt sarežģītus uzdevumus savā lietojumprogrammā, neapdraudot lietotāja pieredzi.

Node.js nodrošina visu nepieciešamo, tostarp tīmekļa darbiniekus, lai panāktu turpmāku paralēlumu ārpus JavaScript galvenā pavediena.