Event Loop
"Macrotasks և Microtasks: Ինչպե՞ս է աշխատում JavaScript-ի շարժիչը:"
Ի՞նչ է Event Loop-ը
JavaScript-ի գործարկման հիմքում ընկած է Event Loop (Իրադարձությունների ցիկլ) գաղափարը: Այն շատ պարզ է՝ կա անվերջ ցիկլ, որտեղ JavaScript-ի շարժիչը սպասում է առաջադրանքների (tasks), կատարում է դրանք, իսկ հետո "քնում է"՝ սպասելով նոր առաջադրանքների:
Տեսակները
Macrotasks (Մակրոթասքեր)
Սրանք հիմնական առաջադրանքներն են, որոնք գալիս են բրաուզերից կամ արտաքին միջավայրից.
-
script(ամբողջական ֆայլի բեռնում և գործարկում) -
Օգտատիրոջ գործողություններ
(
mousemove,click) -
Ժամանակացույցեր
(
setTimeout,setInterval)
Microtasks (Միկրոթասքեր)
Միկրոթասքերը ստեղծվում են հենց մեր կոդի կողմից: Դրանք ավելի բարձր առաջնահերթություն ունեն, քան մակրոթասքերը.
-
Promise-ներ (
.then,.catch,.finally) -
awaitգործողություններ -
queueMicrotask(func)
Ալգորիթմը
Կատարման հերթականությունը
Անմիջապես յուրաքանչյուր Macrotask ավարտելուց հետո, շարժիչը կատարում է ԲՈԼՈՐ Microtask-երը, նախքան որևէ այլ macrotask վերցնելը կամ UI-ը թարմացնելը (rendering):
Գործնական Օրինակ
Ի՞նչ հերթականությամբ կտպվեն թվերը console-ում:
setTimeout(() => console.log(2));
Promise.resolve().then(() => console.log(3));
Promise.resolve().then(() => setTimeout(() => console.log(4)));
Promise.resolve().then(() => console.log(5));
setTimeout(() => console.log(6));
console.log(7);
Պատասխան և Բացատրություն
Արդյունքը կլինի՝ 1 7 3 5 2 6 4
- 1 և 7 - Տպվում են անմիջապես, քանի որ սինխրոն կոդ են:
-
3 և 5 - Տպվում են
հաջորդիվ, քանի որ Microtask-եր են (Promise-ների
.then): Ի դեպ, 4-րդ տողի Promise-ը գցում է նորsetTimeout(4)Macrotask հերթի մեջ: - 2, 6 և 4 - Տպվում են ամենավերջում, քանի որ Macrotask-եր են:
Օգտակար Կիրառություններ
1. CPU ծանրաբեռնող խնդիրների բաժանում
Եթե ունեք շատ ծանր ցիկլ (օրինակ՝ գույների փոփոխություն մեծ
տեքստում կամ 1 միլիարդ հաշվարկ), բրաուզերը կկախի ("hang"),
և կոճակները չեն աշխատի: Կոդը կարելի է բաժանել մասերի և
յուրաքանչյուր մասը դնել setTimeout(func)-ի
մեջ: Այդպիսով, Event Loop-ը «շունչ կքաշի» և կկարողանա այլ
բաներ անել (օրինակ՝ արձագանքել click-երին) կտորների
արանքում:
2. Progress Bar Ցուցադրում
Քանի որ DOM-ի render-ը տեղի է ունենում միայն Task-ի
ավարտից հետո, եթե հսկայական հաշվարկ անեք մեկ Task-ի
ընթացքում, օգտատերը միայն վերջնական արդյունքը կտեսնի: Եթե
հաշվարկը բաժանեք setTimeout-ներով, բրաուզերը
կհասցնի թարմացնել էկրանը և ցույց տալ գործընթացը
(progress):