JavaScript က Single thread တခုတည်းကိုသုံးတယ် အဲ့တာကို ဘယ်လိုလုပ်ပြီးတော့ event handler တွေကို အလုပ်လုပ်သွားတာလဲပေါ့။
တကယ်တမ်းကြတော့ အောက်ကပုံမှာပြထားသလို JavaScript မှာ Stack ရှိတယ်။ သူကရှင်းတယ် JS code တွေကို run တော့မယ်ဆိုရင် method တခုချင်းဆီကို သူ.ဆီပေါ်တင်ပြီးတော့ run တယ်။
ဥပမာ
function one()
{
two();
}
function two()
{
}
one();
ခုနက code ကို run ဖို.ဆို one ကို အရင်ဆုံး JS call stack ပေါ်တင်မယ် ပြီးတော့ သူ.ထဲက code တွေကို run မယ် အဲ့လို one ကို run နေတုန်း two() ကိုခေါ်ထားတာ တွေ.ရင် stack ပေါ်မှာဒီလိုဖြစ်လာမယ်။
two
one
top က အပေါ်ကလို.မှတ်ပေါ့ ဒါဆို two ပြီးသွားရင် control က one ဆီပြန်လာမယ်။ ဘာလို.ဆိုတော့ two ပြီးသွားရင် Call stack ပေါ်ကနေ two ကို pop ချ နောက် သူ.အောက်က calling method one ဆီပြန်လာ။
တခြား language တွေ ဥပမာ Java, C#, အစရှိတာတွေမှာကြတော့ runtime မှာ multiple thread သုံးလို.၇တယ်။ ဆိုပါစို. C# မှာဖြစ်ဖြစ် Java Swing,Android မှာဖြစ်ဖြစ် processing တခုကို main thread (main thread ဆိုတာ programmer က ဘာမှ thread create လုပ်စရာမလိုပဲ main method ကိုစ run တဲ့ thread ကြီး) ကနေ အကြာကြီးခေါ်ရင် UI သည် hang သလိုလို unresponsive ဖြစ်သွားတယ်။ ဒါကြောင့်ခုနက processing အရမ်းကြာမဲ့ကောင်တွေကို GUI thread ကိုလာမထိအောင် ခုနက ကောင်တွေမှာ thread လေးတွေခွဲပြီး run ရင် ပိုအဆင်ပြေတယ်။
ဥပမာ Android မှာ button တခုကိုနှိပ်လိုက်လို. server ကနေ REST API သုံးပြီး data ယူမယ် ဆွဲမယ်ဆိုပါစို. အဲ့တာကို Retrofit နဲ.တခါတည်း main thread ကနေ လှမ်းဆွဲမယ်ဆိုရင် UI သည် responsiveness ကိုထိနိုင်တယ် အဲ့တော့ AsyncTask လိုကောင်မျိုး ကိုသုံးပြီး REST call ကိုခေါ်လိုက်တယ် ဒါဆို UI ကိုမထိတော့ဘူး။
ခုနက JS Node.js မှာကျတော့ ဘာပြဿနာလဲဆိုတော့ Single thread ပဲရှိတယ် အဲ့တော့ ခုနကလို main thread မှာ compuation အကြာကြီးလုပ်နေရင် တခြား event handler တွေ အလုပ်မလုပ်နိုင်တော့ဘူး။ အဲ့တော့ main thread မှာ computation ကို အများကြီးလုပ်ချင်ရင် ဥပမာ array element ၁သောင်းလောက်ကို process လုပ်ရမယ်ဆိုရင် setInterval ဒါမှမဟုတ် setTimout သုံးပြီး ခွဲလုပ်ရတယ်။ ဒါမှ တခြား event handler တွေ အလုပ်လုပ်နိုင်မှာ။
ဒါဆို ခုနက event handler တွေ setInterval, setTimeout က callback တွေ Ajax event call back တွေ run ရတော့မယ်ဆိုရင် JS က ဘာလုပ်လဲဆိုတော့ အဲ့ကောင်တွေကို queue ထဲမှာ တန်းစီထားတယ်။ ဒါဆိုရင် သူတို.ကို ဘယ်အချိန်မှာ ထ run ပေးလဲဆိုတော့ ခုနက main call stack ပေါ်မှာ ဘာမှလုပ်စရာမရှိတော့လို. empty ဖြစ်သွားရင် queue ထဲကနေ ယူပြီး လုပ်ပေးတယ်။ ဒါကြောင့် တကယ်လို.များ ကိုယ်က main thread မှာ processing အကြာကြီးလုပ်နေရင် browser မှာဆို timeout ဖြစ်ပြီး not responsive ဆိုပြီးပြလိမ့်မယ် ။အဲ့ကျ ခုနက event handler တွေ run လို.မရတော့ဘူး။
ေအာက္က code က mozilla ကေန ကူးလာတာ။
const s = new Date().getSeconds();
setTimeout(function() {
// prints out “2”, meaning that the callback is not called //immediately after 500 milliseconds.
console.log(“Ran after ” + (new Date().getSeconds() – s) + ” seconds”);
}, 500);
while(true) {
if(new Date().getSeconds() – s >= 2) {
console.log(“Good, looped for 2 seconds”);
break;
}
}
စစချင်းမှာ
const s = new Date().getSeconds();
ကို call stack ပေါ်တင်မယ် run မယ်နောက် setTimeout() အတွက်ကျတော့ ဘာမှမလုပ်ဘူး Browser API ကိုသုံးပြီး 500 miliseconds ပြည့်သွားရင် queue ထဲကိုထဲ့မယ်
အောက်က code မှာ while(true ) နဲ.ပတ်ထားတယ်။ နောက် 2 second မပြည့်မချင်း breakမလုပ်ဘူး။ ဒါဆိုခုနက setTimeout သည် 500 milisecond ပြည့်သွားလဲ queue ထဲမှာပဲနေရတုန်းမှာ ဘာမှလုပ်လို.မရဘူး ဘာလို.လဲဆိုတော့ main thread call stack empty မဖြစ်သေးလို. ။ main thread က 2 second ပြည့်အောင် loop ပြီးသွားမှ ခုနက queue ထဲက setTimeout callback ကို run လိမ့်မယ်။
event တခုခု ဖြစ်လို. ဥပမာ button click တယ်သူ. event handler ကို run ရမယ်ဆို ချက်ချင်း run တာမဟုတ်ဘူး queue ထဲကို ကောက်ထဲ့တာ အဲ့မှာ call stack ပေါ်မှာ run ဖို.ကုန်ပြီလားဆိုတာကို စောင့်ရမယ် နောက် queue ထဲမှာတောင် သူ.ထက်အရင်ရောက်နေတဲ့ handler တွေ အရင် run ပြီးအောင် စောင့်ရမယ် ။
Node.js ဘက်မှာလဲ အဲ့လိုသဘော event loop ကိုသုံးတယ် သူကျအဆင့်ပိုများတယ်။
အောက်က လင့်မှာ ခုနက stack, queue တွေ ဘယ်လို ထိန်းသွားတယ်ဆိုတာကို visualize ပြထားတာရှိတယ်။

One thought on “JS”