Supratimas, kaip „JavaScript“ vykdo kodą: sinchroniniai ir asinchroniniai modeliai
„JavaScript“ yra vienos gijos kalba, tai reiškia, kad ji vienu metu vykdo vieną kodo eilutę. Kūrėjams labai svarbu suprasti, kaip ji atlieka sinchronines ir asinchronines užduotis. Dažnai klausimai šia tema kyla techniniuose interviu, todėl svarbu nuodugniai suvokti šias sąvokas.
Kai kūrėjai naudoja tokias funkcijas kaip setTimeout arba Pažadai, vykdymo eiga iš pradžių gali atrodyti šiek tiek nenuspėjama. Tačiau vadovaudamiesi aiškia struktūra galite nustatyti tikslią tvarką, kuria bus vykdomos skirtingos jūsų kodo dalys. Tai ypač svarbu sprendžiant atgaliniai skambučiai ir renginių eilės.
Šiame pavyzdyje išskaidysime, kaip „JavaScript“ tvarko tokias sinchronines užduotis kaip console.log ir asinchronines operacijas, pvz setTimeout ir Pažadai. Pasibaigus šiam paaiškinimui, jūs geriau suprasite, kaip „JavaScript“ įvykių ciklas nustato prioritetus ir apdoroja užduotis.
Šis straipsnis skirtas padėti nustatyti „JavaScript“ vykdymo tvarką – naudingą įgūdį sprendžiant interviu klausimus arba derinant asinchroninį kodą. Pasinerkime į praktinį pavyzdį, kad aiškiai parodytume sąvokas.
komandą | Naudojimo pavyzdys |
---|---|
setTimeout() | Ši funkcija suplanuoja kodo vykdymą po nurodyto uždelsimo. Jis naudojamas asinchroninėms užduotims imituoti, pvz., veiksmų atidėjimui arba operacijų atidėjimui į įvykio kilpą. Pavyzdyje jis naudojamas atidėti registravimo "B" ir "E" vykdymą. |
Promise.resolve() | Sukuria pažadą, kuris iš karto išsprendžiamas. Tai naudinga, kai reikia vykdyti asinchroninį kodą, bet nereikia laukti išorinės sąlygos. Pavyzdyje jis naudojamas asinchroniškai įrašyti „D“ po „B“. |
then() | Šiuo metodu prie pažado pridedamas atšaukimas, kuris bus įvykdytas, kai pažadas bus įvykdytas. Tai užtikrina, kad tam tikras kodas bus paleistas pasibaigus asinchroninei užduočiai. Čia jis užtikrina, kad „D“ būtų užregistruotas po įvykdyto pažado. |
Event Loop | Įvykio ciklas yra mechanizmas, tvarkantis asinchroninių užduočių vykdymą JavaScript. Nors tai nėra tiesioginė komanda, jos funkcijos supratimas yra labai svarbus norint paaiškinti operacijų tvarką kode. Jis apdoroja užduotis iš atgalinio skambinimo eilės po to, kai išvalomas dabartinis dėklas. |
Microtask Queue | Tai prioritetinė užduočių, pvz., įvykdytų pažadų, eilė. Mikroužduotys (pvz., įvykdyti pažadai) vykdomos prieš užduotis iš įvykių ciklo užduočių eilės (pvz., setTimeout atgaliniai iškvietimai). Štai kodėl „D“ registruojasi prieš „E“. |
Console.log() | Naudojamas spausdinti pranešimus į konsolę derinimo tikslais. Šiame kontekste tai naudinga norint sekti sinchroninio ir asinchroninio kodo vykdymo tvarką. |
Callback Queue | Atgalinio iškvietimo eilėje saugomos užduotys, kurios yra paruoštos vykdyti, kai dabartinis kodo vykdymas bus baigtas, pvz., funkcijos, perduotos setTimeout. Įvykio ciklas perkelia šias užduotis į skambučių krūvą. |
Zero Delay | Kai setTimeout() delsa nustatyta į 0, atgalinis skambutis vykdomas atlikus visas sinchronines užduotis ir mikroužduotis. Pavyzdyje atgalinis skambutis su „E“ vykdomas po „D“, net jei jo delsa yra 0. |
Asynchronous Execution | Tai yra programavimo paradigma, kai tam tikros operacijos vykdomos atskirai nuo pagrindinio kodo srauto, leidžianti „JavaScript“ atlikti tokias užduotis kaip tinklo užklausos ar laikmačiai, neužblokuojant pagrindinės gijos. |
„JavaScript“ vykdymo srauto tyrinėjimas: sinchroninis ir asinchroninis kodas
„JavaScript“ labai svarbu suprasti sinchroninio ir asinchroninio kodo vykdymo tvarką, ypač kai setTimeout ir Pažadai. Svarbiausia suprasti, kaip įvykių ciklas pirmiausia apdoroja sinchronines užduotis, o tada pereina prie eilėje esančių asinchroninių užduočių tvarkymo. Pateiktame kodo pavyzdyje pirmieji du žurnalai („A“ ir „F“) yra sinchroniniai, ty jie vykdomi tokia tvarka, kokia yra rodomi kode. Kai jie vykdomi, scenarijus iš karto suplanuoja asinchronines užduotis, pvz., setTimeout, kad būtų galima vėliau apdoroti.
Funkcija setTimeout yra įprastas būdas atidėti operacijas, sukuriant vykdymo eigos vėlavimo pojūtį. Šiuo atveju abu setTimeout funkcijos naudojamos konsolės žurnalams "B" ir "E" įtraukti į įvykių eilę. Svarbu pažymėti, kad nors „E“ uždelsimas yra 0 milisekundžių, jis vis tiek patenka į eilę, kai dabartinės sinchroninės operacijos ir mikroužduotys yra baigtos. Suprasti šį subtilų skirtumą labai svarbu nustatant sudėtingesnių „JavaScript“ užduočių vykdymo tvarką.
Pirmojo viduje setTimeout atgalinio skambučio, žurnalas „B“ išspausdinamas pirmiausia, nes jis vis dar yra sinchroninės užduočių eilės dalis, kuriai teikiama pirmenybė. Tada per tą skambutį sukuriamas įvykdytas pažadas Pažadėk.išspręsti. Tai suaktyvina mikroužduotį, kuri užtikrina, kad žurnalas „D“ įvyktų po „B“, bet prieš bet kokias kitas užduotis pagrindinio įvykio eilėje. Toks pažadų, įtrauktų į mikroužduočių eilę, elgesys leidžia „D“ įrašyti prieš antrąjį setTimeout atgalinio skambinimo žurnalą „E“. Taigi mikroužduotys turi pirmenybę prieš standartines asinchronines užduotis.
Apibendrinant galutinę vykdymo tvarką: „A“ ir „F“ registruojami sinchroniškai, o po to „B“, kuris yra eilėje pagal pirmąjį setTimeout. Išspręstas pažadas lemia, kad „D“ bus užregistruotas kaip mikroužduotis. Galiausiai „E“ registruojamas paskutinis, nes jis yra antrosios dalies dalis setTimeout atgalinis skambutis. Šis „JavaScript“ vykdymo srauto supratimas, derinant sinchronines užduotis, įvykių kilpą ir mikroužduotį, yra neįkainojamas atsakant į interviu klausimus arba derinant asinchroninį kodą realaus gyvenimo projektuose.
„JavaScript“ sinchroninio ir asinchroninio vykdymo įvairiuose scenarijuose supratimas
Šis scenarijus demonstruoja „JavaScript“ įvykių ciklo mechanizmą, naudodamas sinchroninių ir asinchroninių operacijų derinį.
console.log("A");
setTimeout(() => {
console.log("B");
Promise.resolve("C").then(() => console.log("D"));
}, 1000);
setTimeout(() => console.log("E"), 0);
console.log("F");
„JavaScript“ vykdymo analizė: sutelkite dėmesį į įvykio kilpą
Šis pavyzdys grindžiamas ankstesniu, parodydamas, kaip įvykių ciklas apdoroja eilėje esančias užduotis skirtingais laiko scenarijais.
console.log("Start");
setTimeout(() => {
console.log("Middle");
}, 500);
Promise.resolve().then(() => {
console.log("Promise 1");
});
console.log("End");
Giliai pasinerkite į „JavaScript“ įvykių kilpą ir užduočių prioritetų nustatymą
Pagrindinis „JavaScript“ asinchroninio veikimo aspektas yra renginio kilpa, kuri yra atsakinga už atgalinių skambučių, pažadų ir kito asinchroninio kodo vykdymą. Ši įvykių kilpa nuolat tikrina, ar skambučių krūva tuščia, o jei taip, apdoroja užduotis iš atgalinio skambinimo eilės ir mikroužduočių eilės. Suprasti, kaip šiose eilėse teikiamos užduočių prioritetas, labai svarbu užtikrinti, kad kodas veiktų taip, kaip tikėtasi, ypač tvarkant setTimeout ir pažadai vienu metu.
Mikroužduočių eilė turi viršenybę prieš atgalinio skambinimo eilę. Užduotys kaip pažadėti rezoliucijas dedami į mikroužduočių eilę, tai reiškia, kad jos vykdomos prieš bet kokias atidėtas užduotis iš atgalinio skambinimo eilės, net jei setTimeout uždelsimas lygus nuliui. Štai kodėl kodo pavyzdyje žurnalas „D“ iš pažado vykdomas prieš žurnalą „E“ iš antrojo setTimeout. Labai svarbu, kad kūrėjai tai suprastų rašydami kodą, kuris maišo asinchronines operacijas, kad išvengtų netikėto elgesio.
Realiose programose asinchroninės operacijos, pvz., API skambučiai ar laikmačiai, dažnai sąveikauja su sinchroniniu kodu. Žinodami, kaip veikia įvykių ciklas, atgalinio skambinimo eilė ir mikroužduočių eilė, kūrėjai gali geriau numatyti savo kodo rezultatus. Tai ypač svarbu optimizuojant našumą arba derinant sudėtingus scenarijus, kai abu asinchroninės operacijos ir sinchroninis kodas sąveikauja dažnai.
Dažnai užduodami klausimai apie „JavaScript“ vykdymo tvarką
- Kas yra „JavaScript“ įvykių ciklas?
- Įvykio ciklas yra mechanizmas, kurį „JavaScript“ naudoja asinchroninių operacijų vykdymui, pvz., suaktyvinamoms setTimeout arba Promises.
- Kaip veikia setTimeout dirbti?
- setTimeout suplanuoja atgalinį skambutį vykdyti po nurodytos delsos, tačiau jis įtraukiamas į atgalinio skambučio eilę ir vykdomas tik apdorojus visą sinchroninį kodą ir mikroužduotys.
- Kodėl a Promise išspręsti prieš a setTimeout su 0 vėlavimu?
- Pažadai dedami į mikroužduočių eilę, kuri turi didesnį prioritetą nei atgalinio skambinimo eilė, kur setTimeout pateikiami atgaliniai skambučiai.
- Kuo skiriasi atgalinio skambinimo eilė ir mikroužduočių eilė?
- Atgalinio skambinimo eilė naudojama setTimeout ir kitas asinchronines operacijas, o mikroužduočių eilė tvarko tokias užduotis kaip Promise rezoliucijas ir apdoroja juos prieš skambinant.
- Kam skirta vykdymo tvarka console.log pateiktame pavyzdyje pateiktus teiginius?
- Tvarka yra „A“, „F“, „B“, „D“, „E“, dėl to, kaip sinchroninės ir asinchroninės užduotys yra tvarkomos įvykių cikle.
„JavaScript“ vykdymo modelio užbaigimas
Norint suprasti, kaip tai padaryti, labai svarbu suprasti „JavaScript“ įvykių kilpą asinchroninis tokios operacijos kaip setTimeout ir Pažadai yra įvykdyti. Tai padeda kūrėjams užtikrinti, kad jų kodas veiktų taip, kaip tikėtasi, ir išvengti įprastų spąstų atliekant kelias užduotis.
Šiame pavyzdyje galutinė „A“, „F“, „B“, „D“ ir „E“ vykdymo tvarka iliustruoja, kaip mikroužduotys (pažadai) turi pirmenybę prieš iškvietimus iš setTimeout. Šios žinios yra neįkainojamos interviu klausimams ir realaus gyvenimo kodavimo iššūkiams.
„JavaScript“ vykdymo tvarkos nuorodos ir šaltiniai
- Plėtojamas įvykių ciklas ir užduočių prioritetų nustatymo sąvokos „JavaScript“. MDN žiniatinklio dokumentai – įvykių ciklas
- Aptaria elgesį Pažadai ir setTimeout asinchroninio JavaScript kodo vykdymo metu. JavaScript informacija – mikroužduočių eilė
- Paaiškina sinchroninių ir asinchroninių užduočių vykdymo tvarką naudojant JavaScript pavyzdžius. freeCodeCamp – „JavaScript“ pažadų supratimas