JavaScripti täitmismudel on nüansirikas ja seda on lihtne valesti mõista. Sündmuste tsükli põhiolemuse tundmaõppimine võib aidata.

JavaScript on ühe lõimega keel, mis on loodud toimima ükshaaval. Sündmustsükkel võimaldab aga JavaScriptil sündmusi ja tagasihelistusi asünkroonselt käsitleda, emuleerides samaaegseid programmeerimissüsteeme. See tagab teie JavaScripti rakenduste jõudluse.

Mis on JavaScripti sündmuste silmus?

JavaScripti sündmuste silmus on mehhanism, mis töötab iga JavaScripti rakenduse taustal. See võimaldab JavaScriptil käsitleda ülesandeid järjestikku, blokeerimata selle peamist täitmislõimi. Seda nimetatakse asünkroonne programmeerimine.

Sündmustsükkel hoiab tööülesannete järjekorda ja suunab need ülesanded paremale veebi API täitmiseks ükshaaval. JavaScript jälgib neid ülesandeid ja käsitleb neid vastavalt ülesande keerukuse tasemele.

Et mõista JavaScripti sündmuste tsükli ja asünkroonse programmeerimise vajadust. Peate mõistma, millise probleemi see sisuliselt lahendab.

Võtke see kood näiteks:

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

See kood määratleb kõigepealt funktsiooni, mida nimetatakse longRunningFunction(). See funktsioon teeb mingi keerulise aeganõudva ülesande. Sel juhul täidab see a jaoks tsükli iteratsioon üle 100 000 korra. See tähendab, et console.log("Tere") jookseb 100 000 korda üle.

Sõltuvalt arvuti kiirusest võib see võtta kaua aega ja tõkestada shortRunningFunction() kohesest täitmisest kuni eelmise funktsiooni lõpuni.

Siin on konteksti jaoks mõlema funktsiooni käitamiseks kuluva aja võrdlus:

Ja siis singel shortRunningFunction():

Erinevus 2351-millisekundilise ja 0-millisekundilise toimingu vahel on ilmne, kui eesmärk on luua toimiv rakendus.

Kuidas sündmuste ahel aitab rakenduse jõudlust parandada

Sündmustsüklil on erinevad etapid ja osad, mis aitavad süsteemi tööle panna.

Kõnede virn

JavaScripti kõnede pinu on oluline selleks, kuidas JavaScript teie rakenduse funktsiooni- ja sündmusekutseid käsitleb. JavaScripti kood kompileeritakse ülalt alla. Kuid Node.js määrab koodi lugemisel funktsioonikutsed alt üles. Lugedes surub see määratletud funktsioonid raamidena ükshaaval kõnevirna.

Kõnepinn vastutab täitmiskonteksti ja funktsioonide õige järjekorra säilitamise eest. See teeb seda LIFO (Last-In-First-Out) pinuna.

See tähendab, et viimane funktsioonikaader, mille teie programm kõnepinu surub, hüppab esimesena pinust välja ja käivitab. See tagab, et JavaScript säilitab funktsioonide täitmise õiges järjekorras.

JavaScript tõstab iga kaadri virnast välja, kuni see on tühi, mis tähendab, et kõik funktsioonid on töötamise lõpetanud.

Libuv Web API

JavaScripti asünkroonsete programmide keskmes on libuv. Libuv teek on kirjutatud C programmeerimiskeeles, mis suudab suhelda operatsioonisüsteemi omadega madala taseme API-d. Teek pakub mitmeid API-sid, mis võimaldavad JavaScripti koodil paralleelselt käitada kood. API-d lõimede loomiseks, API lõimedevaheliseks suhtlemiseks ja API lõimede sünkroonimise haldamiseks.

Näiteks kui kasutate setTimeout failis Node.js täitmise peatamiseks. Taimer seadistatakse libuv kaudu, mis haldab sündmuse tsüklit, et pärast määratud viivituse möödumist tagasihelistamisfunktsiooni käivitada.

Samamoodi, kui teete võrgutoiminguid asünkroonselt, tegeleb libuv need toimingud mitteblokeerivalt viisil, tagades, et teised ülesanded saavad töötlemist jätkata, ootamata sisend/väljund (I/O) operatsiooni lõpp.

Tagasihelistamise ja sündmuste järjekord

Tagasihelistamise ja sündmuste järjekord on koht, kus tagasihelistamisfunktsioonid ootavad täitmist. Kui asünkroonne toiming libuvist lõpetatakse, lisatakse sellele järjekorda vastav tagasihelistamisfunktsioon.

Jada läheb järgmiselt:

  1. JavaScript teisaldab asünkroonsed ülesanded libuvisse, et see saaks hakkama, ja jätkab kohe järgmise ülesande käsitlemist.
  2. Kui asünkroonne ülesanne lõpeb, lisab JavaScript tagasihelistamise järjekorda oma tagasihelistamisfunktsiooni.
  3. JavaScript jätkab kõnevirnas olevate muude ülesannete täitmist, kuni kõik praeguses järjekorras on tehtud.
  4. Kui kõnepinn on tühi, vaatab JavaScript tagasihelistamise järjekorda.
  5. Kui järjekorras on tagasihelistamine, tõukab see esimese kõne pinu ja käivitab selle.

Nii ei blokeeri asünkroonsed ülesanded põhilõime ja tagasihelistamise järjekord tagab, et nende vastavad tagasihelistamised käivituvad nende lõpetamise järjekorras.

Sündmustsükli tsükkel

Sündmustsüklil on ka midagi, mida nimetatakse mikroülesannete järjekorraks. See sündmusetsükli eriline järjekord sisaldab mikroülesandeid, mis on kavandatud täitma niipea, kui praegune ülesanne kõnevirnas on lõpule viidud. See täitmine toimub enne järgmist renderdus- või sündmusetsükli iteratsiooni. Mikroülesanded on kõrge prioriteediga ülesanded, mis on sündmustetsükli tavaülesannete suhtes ülimuslikud.

Promisesiga töötamisel luuakse tavaliselt mikroülesanne. Kui lubadus lahendab või lükkab tagasi, vastab see sellele .hen() või .catch() tagasihelistamised liituvad mikroülesannete järjekorda. Saate seda järjekorda kasutada ülesannete haldamiseks, mis vajavad kohest täitmist pärast praegust toimingut (nt rakenduse kasutajaliidese värskendamine või olekumuudatuste käsitlemine).

Näiteks veebirakendus, mis hangib andmeid ja värskendab allalaaditud andmete põhjal kasutajaliidest. Kasutajad saavad selle andmete toomise käivitada, klõpsates korduvalt nuppu. Iga nupuklõps käivitab asünkroonse andmeotsingutoimingu.

Ilma mikroülesanneteta töötaks selle ülesande sündmusesilmus järgmiselt:

  1. Kasutaja klõpsab nuppu korduvalt.
  2. Iga nupuklõps käivitab asünkroonse andmete toomise toimingu.
  3. Kui andmete toomise toimingud on lõppenud, lisab JavaScript neile vastavad tagasihelistamised tavalisse ülesannete järjekorda.
  4. Sündmustsükkel alustab tavaliste ülesannete järjekorras olevate ülesannete töötlemist.
  5. Andmete toomise tulemustel põhinev kasutajaliidese värskendus käivitub niipea, kui tavatoimingud seda võimaldavad.

Mikroülesannete puhul töötab sündmuste ahel aga teisiti:

  1. Kasutaja klõpsab nuppu korduvalt ja käivitab asünkroonse andmete toomise toimingu.
  2. Kui andmete toomise toimingud on lõppenud, lisab sündmusesilmus neile vastavad tagasihelistamised mikrotegumite järjekorda.
  3. Sündmustsükkel alustab mikroülesannete järjekorras olevate ülesannete töötlemist kohe pärast praeguse ülesande täitmist (nupuklõps).
  4. Andmete toomise tulemustel põhinev kasutajaliidese värskendus käivitub enne järgmist tavatoimingut, pakkudes paremini reageerivat kasutuskogemust.

Siin on koodinäide:

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

Selles näites helistab iga klõps nupul „Fetch”. too andmed (). Iga andmete toomise toimingute ajakava mikroülesandena. Tootud andmete põhjal käivitub kasutajaliidese värskendus kohe pärast iga toomistoimingu lõppemist, enne mis tahes muid renderdus- või sündmusetsükli ülesandeid.

See tagab, et kasutajad näevad värskendatud andmeid ilma sündmuste tsükli muudest ülesannetest tingitud viivitusi.

Mikroülesannete kasutamine sellistes stsenaariumides võib takistada kasutajaliidese jagamist ning pakkuda teie rakenduses kiiremat ja sujuvamat suhtlust.

Sündmustsükli mõju veebiarendusele

Toimivate ja tundlike rakenduste loomiseks on oluline mõista sündmuste tsüklit ja selle funktsioone. Sündmustsükkel pakub asünkroonseid ja paralleelseid võimalusi, nii et saate oma rakenduses tõhusalt lahendada keerulisi ülesandeid ilma kasutajakogemust kahjustamata.

Node.js pakub kõike, mida vajate, sealhulgas veebitöötajaid, et saavutada täiendav paralleelsus väljaspool JavaScripti põhilõimi.