Ինչպես է JavaScript-ը աշխատում գլխարկի տակ

Ամենատարածված հարցը, որին մենք հանդիպում ենք, հետևյալն է. Մարդկանց մեծամասնությունը պատրաստ է այո պատասխանին, JavaScript-ը համաժամանակյա լեզու է և գործում է ասինխրոն, թեև երբ ծագում է երկրորդ հարցը. Ինչպե՞ս է JavaScript-ն աշխատում ասինխրոն: Շատերին չի հաջողվում պատշաճ բացատրություն տալ դրան: Այդ հարցի պատասխանը Իրադարձությունների հանգույց հասկացության միջոցով է: Եկեքհասկանանք Event Loop-ը և ինչպես է գործում Event Loop-ը:

Event Loop-ի հիմնական ճարտարապետությունը

Եկեք նախ հասկանանք իրադարձությունների հանգույցի յուրաքանչյուր հատվածը, նախքան խորասուզվելը, թե ինչպես է աշխատում իրադարձությունների հանգույցը:

Կույտ:

Heap-ը հիշողության մեջ պահեստային տարածք է, որտեղ օբյեկտները պահվում են, երբ օգտագործողը սահմանում է փոփոխական:

Call Stack:

Զանգի կույտը ոչ այլ ինչ է, եթե ոչ ստեկի տվյալների կառուցվածք, որն աշխատում է LIFO ձևաչափով, որը վերջինն է առաջինը: Եկեք ավելի լավ հասկանանք, թե ինչ է զանգերի փաթեթը և ինչպես է այն աշխատում:

function human(){
 console.log("Inside human function");
}
function animal(){
 human();
 console.log("Inside animal function");
}
animal();

Հուզված եք իմանալ, թե ինչպես է աշխատում վերը նշված կոդը:

Ինչպես տեսնում ենք վերը նշված օրինակից, սկզբում animal()-ը մտնում է stack-ը և այնուհետև կանչում է human() ֆունկցիան: Օրինակի համար արդյունքը կլինի.

Inside human function
Inside animal function

Սա պարզ օրինակ է, թե ինչպես է JavaScript-ը աշխատում համաժամանակյա:

Վեբ API:

Ենթադրենք, որ զանգերի կույտում կա արգելափակող կոդ, ինչպիսին է երկար ցիկլի կամ API զանգի դեպքում: Զանգերի կույտը կկատարի այդ գործողությունը, մինչդեռ մյուս գործառույթները, որոնք գտնվում են կույտում կամ որոնք պետք է մղվեն կույտում, կարգելափակվեն:

Օրինակ՝ եթե կա 0-ից մինչև 1 միլիոն for օղակ, զանգերի կույտը նախ կիրականացնի զանգերի փաթեթը և կարգելափակի մյուս գործողությունները, մինչև «for» հանգույցը գործարկվի: Նման սցենարներից խուսափելու համար մենք ունենք Web API: Վեբ API-ն առանձին մշակում է զանգերի կույտի արգելափակման կոդերը, որպեսզի զանգերի կույտը արգելափակված չլինի: Նշեք նաև, որ հետին պլանի նպատակների համար մենք ունենք c++ API-ներ Web API-ների փոխարեն ինչպես NodeJs-ում:

Հետկանչի հերթ.

Հետ կանչի հերթը կրկին ոչ այլ ինչ է, քան հերթի տվյալների կառուցվածքը, որը հետևում է First-in First-out (FIFO): Ամեն անգամ, երբ մի ֆունկցիա կամ կոդ, որն արդեն գործարկվել է Web API-ում, այն փոխանցում է հետ կանչի հերթին, որն այնուհետև, ավելի ուշ, գործառույթը մղում է զանգերի կույտ, երբ զանգերի կույտը պարզ է, տպելու այդ ֆունկցիայի արդյունքը:

Ինչպե՞ս է գործում իրադարձությունների հանգույցը:

Իրադարձությունների հանգույցի աշխատանքը բացատրելու համար եկեք մի փոքր օրինակ վերցնենք և տեսնենք, թե ինչպես է կատարվում կոդը:

function eventLoopExample(){
    console.log("First console");
    setTimeout(function(){console.log("Second console")}, 0);
    console.log("Third console");
}
eventLoopExample();

Որոշ ժամանակ տրամադրեք վերը նշված ֆունկցիայի արդյունքը գուշակելու համար, նախքան ստորև նշված պատասխանը ստուգելը:

Քանի որ մենք տեսանք վերը նշված արդյունքը, մենք բոլորս կարող ենք մտածել, թե ինչպես վերջապես ստացանք Երկրորդ կոնսոլը, պատասխանը Event Loop-ի միջոցով է: Ինչպես վերը քննարկեցինք, eventLoopExample()-ը կմտնի փաթեթ, որին հաջորդում է առաջին վահանակը: Այնուհետև զանգերի կույտը վերադարձնում է ելքը առաջին վահանակի համար և մղում է երրորդ տողը, որը setTimeout() է, որն այնուհետև մտնում է զանգերի կույտ, և քանի որ սա համաժամանակյա ֆունկցիա է, այն ուղարկվում է Web API, որն այնուհետև կատարում է գործառույթը և ուղարկում գործառույթը դեպի Կատարումից հետո հետադարձ կապի հերթ: Դրան զուգահեռ զանգերի կույտը կհրաժարվի բուրգի երրորդ կոնսոլից, որը կատարվում է և ելքը վերադարձվում է: Այնուհետև, երբ զանգերի կույտը դատարկվի/ջնջվի, հերթում առկա երկրորդ վահանակն այնուհետև մղվում է դեպի զանգերի կույտ, որն այնուհետև վերադարձնում է ելքը:

Վերջին հարցը, որը մեզանից քչերը կունենան, այն է, որ setTimeout()-ում ժամանակը տրվել է որպես 0, ինչը նշանակում է, որ setTimeout-ը պետք է կատարվեր անմիջապես զանգերի փաթեթում, այնուամենայնիվ, վերջապես մխիթարվում է, թե ինչու: Սրա հիմքում ընկած պատճառն այն է, որ setTimeout()-ի ասինխրոն ֆունկցիան միշտ կուղարկվի վեբ API-ին և հետևաբար հետ կանչի հերթին: Թեև հետ կանչի հերթը արդեն կատարել է setTimeout()-ը, այն դեռ սպասում է, որ բուրգը մաքրվի: Լռելյայնորեն, հետ կանչի հերթը միշտ ստուգվում է յուրաքանչյուր 10 ms-ից հետո, եթե ներսում առկա գործառույթներն ավարտել են կատարումը, թե ոչ:

Եզրակացություն

Թեև սա շատ հիմնական ներածություն է այն մասին, թե ինչպես է JavaScript-ը աշխատում ասինխրոն, մենք դեռ հստակ պատկերացում ունենք, թե ինչպես է JavaScript-ը աշխատում գլխարկի տակ: Դա ընդամենը մի ցիկլ է զանգերի կույտից դեպի վեբ API և վեբ API-ներից մինչև հետադարձ կապի հերթ և վերջապես հետադարձ կապի հերթից մինչև զանգերի կույտ:

Ավելի մանրամասն իմանալու համար, թե ինչպես է JavaScript-ը աշխատում գլխարկի տակ, ես խստորեն խորհուրդ կտամ ստուգել Ֆիլիպ Ռոբերտսի այս տեսանյութը
https://youtu.be/8aGhZQkoFbQ