টাস্ক কিউ
ব্রাউজার কাজ শেষ করার পর কলব্যাকটা সরাসরি চালায় না। স্ট্যাক তখন ব্যস্ত থাকতে পারে। তাই কলব্যাকটা একটা কিউতে গিয়ে অপেক্ষা করে।
ইভেন্ট লুপের কাজ একটাই, আর সেটা খুব সহজ:
স্ট্যাক খালি? তাহলে কিউ থেকে একটা কাজ তুলে স্ট্যাকে বসাও।
দুটো কিউ, সমান নয়
এখানেই বেশিরভাগ বিভ্রান্তি।
| কিউ | কারা যায় | অগ্রাধিকার |
|---|---|---|
| মাইক্রোটাস্ক | প্রমিজ, queueMicrotask, MutationObserver | বেশি |
| ম্যাক্রোটাস্ক | setTimeout, setInterval, ক্লিক, নেটওয়ার্ক ইভেন্ট | কম |
স্ট্যাক খালি হলে ইভেন্ট লুপ পুরো মাইক্রোটাস্ক কিউ খালি করে, তারপর একটা ম্যাক্রোটাস্ক নেয়। একটা নয় — পুরোটা।
console.log('১')
setTimeout(() => console.log('২'), 0)
Promise.resolve().then(() => console.log('৩'))
console.log('৪')
আউটপুট: ১, ৪, ৩, ২।
১ আর ৪ সরাসরি চলে, কারণ ওরা স্ট্যাকেই আছে। তারপর স্ট্যাক খালি হয়।
৩ মাইক্রোটাস্ক, তাই আগে। ২ ম্যাক্রোটাস্ক, তাই শেষে — 0 মিলিসেকেন্ড
লেখা থাকা সত্ত্বেও।
মাইক্রোটাস্ক দিয়ে পেজ আটকে দেওয়া
যেহেতু লুপ পুরো মাইক্রোটাস্ক কিউ খালি করে তবেই এগোয়, একটা মাইক্রোটাস্ক যদি নিজেই আরেকটা মাইক্রোটাস্ক যোগ করতে থাকে, কিউ কখনো খালি হয় না:
function চিরকাল() {
Promise.resolve().then(চিরকাল)
}
চিরকাল()
পেজ জমে যাবে। while (true)-এর মতোই, কিন্তু দেখতে নিরীহ — কারণ কোডে কোনো
লুপ নেই।
মনে রাখার মতো
- স্ট্যাক খালি না হলে কোনো কলব্যাক চলে না।
- মাইক্রোটাস্ক সবসময় ম্যাক্রোটাস্কের আগে।
- মাইক্রোটাস্ক কিউ পুরোটা খালি হয়, একটা করে নয়।
- টাইমারের সময় মানে সর্বনিম্ন দেরি।