জাভাস্ক্রিপ্ট ইভেন্ট লুপ
— আসেন কানে কানে একটা সিক্রেট বলি। ‘জাভাস্ক্রিপ্ট একটি সিঙ্গেল থ্রেডেড ল্যাঙ্গুেজ।’
— কিন্তু, কিন্তু, তাহলে অ্যাসিনক্রোনাস হয় কিভাবে?
— আরে ভাই, অ্যসিনক্রোনাস হতে হলে মাল্টি-থ্রেডেড হতে হবে এমন কথা কই পাইলেন? লেখা আছে কোথাও?
—তাহলে এই কোডটা দেখেন। আপনি কি বলতে চান এই দুইটা রিকোয়েস্ট একটা শেষ হওয়ার পর আরেকটা শুরু হবে? পাইথনের মত?
ধুর মিয়া আপনি কিছু জানেন না। জাভাস্ক্রিপ্ট হইল অ্যাসিনক্রোনাস ল্যাঙ্গুয়েজ।
— আচ্ছা শোনেন তাহলে। জাভাস্ক্রিপ্ট ইন্জিনগুলো অনেকটা কাউন্টারের মত। আর আমরা যেসব কোড লিখি সেগুলো হল কাস্টমারের মত। ইন্জিনগুলো সেগুলোকে একটি লাইনে দাঁড় করায় তারপর একের পর এক এক্সিকিউট করে। যেমন এই কোডটা দেখুন-
এখনে কি হবে? প্রথমে তিনটি স্টেটমেন্ট লাইনে দাড়াবে। একের পর এক এক্সিকিউট হবে। তিন নম্বর স্টেটমেন্ট এক্সিকিউট করার সময় দেখবে সেখানে আবার অন্য একটা ফাংশন ১০০ মিলিসেকেন্ড পরে এক্সিকিউট করার কথা বলা হচ্ছে। তো ইন্জিন সেটা নোট করে রাখবে এবং ১০০ মিলিসেকেন্ড পরে সেই ফাংশনটাকে লাইনে ঢুকিয়ে দেবে। কোন পর্যায়েই দুটি স্টেটমেন্ট একসাথে এক্সিকিউট করেবে না। বিশ্বাস না হলে নিচের কোডটি চালিয়ে দেখতে পারেন।
এখানে a, b দুইটা ফাংশনই ০ মিলিসেকেন্ড পরে মানে সাথে সাথে এক্সিকিউট করতে বলা হচ্ছে। a ফাংশনে একটু বড় ক্যালকুলেশন করা হচ্ছে, তাই বেশ কিছুটা সময় লাগছে। জাভাস্ক্রিপ্ট মাল্টিথ্রেডেড হলে a শেষ হওয়ার আগেই b শুরু হয়ে যাওয়ার কথা না? কিন্তু b সব সময়ই a এর পরে শুরু হবে।
— আচ্ছা। সেটা না হয় বুঝলাম। কিন্তু আমার আগের প্রশ্নের উত্তর কিন্তু পাইনি।
— এখন কথা হল, ব্রাউজার বা নোড অ্যাপের সব কাজ কিন্তু জাভাস্ক্রিপ্টে হয় না। বরং অনেক কিছুই হোস্ট সিস্টেমে (যেমন- ব্রাউজার) হয়। যখন কোন ajax কল করা হয় তাখন টিসিপি কানেকশন খুলে ডাটা নিয়ে আসার দায়িত্বি হোস্ট সিস্টেমের কাছে চলে যায়। আর জাভাস্ক্রিপ্ট ইন্জিন লাইনের পরবর্তী স্টেটমেন্ট এক্সিকিউট করতে থাকে। ajax এর কাজ শেষ হলে আবার রেজাল্টসহ কলব্যাক লাইনে দাঁড়িয়ে যায়। তখন লাইনে আর কিছু না থাকলে সাথে সাথেই কলব্যাক এক্সিকিউট হবে আর থাকলে সেটা শেষ হওয়ার পর কলব্যাক এক্সিকিউট হবে।
অন্যান্য ল্যাঙ্গুয়েজের সাথে জাভাস্ক্রিপ্টের পার্থক্যটা হল এর নন-ব্লকিং বৈশিষ্ট্য। মানে কোন সিস্টেম প্রসেস যেমন ajax কল শেষ হওয়ার জন্য অপেক্ষা না করে পরবর্তী কোড এক্সিকিউট করতে শুরু করে।
এখন হোস্ট সিস্টেম একসাথে কয়টা রিকুয়েস্ট প্রসেস করছে সেটা ডিপেন্ড করবে হোস্টের উপর, কিন্তু জাভাস্ক্রিপ্ট ইন্জিন কখনোই একসাথে একটার বেশি স্টেটমেন্ট প্রসেস করবে না।
আর এই যে লাইনের কথা বললাম সেটাই হল জাভাস্ক্রিপ্ট ইভেন্ট লুপ।
— ও আচ্ছা। এখন বুঝলাম। একবার socket.io ব্যবহার করার সময় জানতে ইচ্ছা করছিল একসাথে সর্বোচ্চ কয়টা কানেকশন হ্যান্ডেল করা যাবে। StackOverflow তে দেখেছিলাম, ইন থিওরি মেমরিতে যতটা কানেকশন অবজেক্ট রাখা সম্ভব ততটা! ব্যাপারটা খুব অদ্ভুত লেগেছিল। কিন্তু আসলে ত সবগুলো কানেকশন কখনোই একসাথে হ্যান্ডেল হবে না। বরং একটার পর একটা হ্যান্ডেল হবে।
— হুমম্।
— আচ্ছা এইগুলা কি জানার কোন দরকার আছে? এতদিন তো জানতাম না জনেও ভালই চলছিল।
— অবশ্যই আছে। মনে করুন আপনার কাছে কয়েক লক্ষ অবজেক্টের একটা লিস্ট আছে। এগুলোকে প্রসেস করে একটা রেজাল্ট বের করতে হবে। এখন সবগুলো যদি একসাথে প্রসেস করতে চান তাহলে কিন্তু বেশ কিছু সময় লেগে যাবে। এই সময়টুকুতে জাভাস্ক্রিপ্ট ইন্জিন পুরোপুরি ব্যাস্ত থাকবে, ফলে ব্রাউজারের অন্যান্য ইভেন্টে রেসপন্স করতে পারবে না। ফলে কার্যত ঐ সময়টাতে পেজটা ইরেসপন্সিভ হয়ে থাকবে। যেমনটা এই এক্সাম্পলটাতে দেখতে পাচ্ছেন।এখানে যতক্ষন processList
এক্সিকিউট হচ্ছে ততক্ষন পেজটা রেসপন্স করছে না।
এটাকে আমরা এভাবে সমাধান করতে পারি। পুরোটা লিস্ট একবারে প্রসেস না করে, এটিকে ভেঙ্গে ভেঙ্গে প্রসেস করতে পারি। তাহলে লম্বা একটা প্রসেস ইভেন্ট লুপ বেশি সময়ের জন্য ব্লক করে রাখছে না। বরং ছোট ছোট অনেকগুলো প্রসেস লুপে ঢুকছে। ফলে অন্যান্য প্রসেসও (যেমন- চেকবক্সের অনক্লিক) মাঝখানে ঢুকতে পারছে।
বিস্তারিত জানতে এখানে দেখতে পারেন। ধন্যবাদ।