যদি আপনি একটি ইঞ্জিনিয়ার বা ডেভেলপার হন যিনি ভিন্ন প্রোগ্রামিং ল্যাঙ্গুয়েজ থেকে আসেছেন, তবে আপনি হয়তো sleep() নামে একটি নেটিভ মেথড ব্যবহার করেছেন একটি মেথড এক্সিকিউট হওয়া থেকে স্টল বা পজ করার জন্য। JavaScript-এ এমন কোনো নেটিভ মেথড নেই।
এই আর্টিকেলে, আমরা দুইটি ভিন্ন উপায় নিয়ে আলোচনা করব যেগুলো ব্যবহার করে JavaScript-এ একটি স্লিপ ফাংশন সিমুলেট করা যায়: Promise এবং async/await ফাংশন।
অ্যাসিঙ্ক্রোনাস ফাংশনগুলির পরিচিতি
আমাদের setTimeout() মেথডকে সংক্ষেপে মেনশন না করলে JavaScript-এ Promise বা async/await ফাংশন সম্পর্কে কথা বলা উচিত নয়। এই মেথডটি দেখাবে কেন Promise JavaScript-এ প্রয়োজন।
JavaScript একক-থ্রেডেড
যখন আমরা বলি JavaScript একটি একক-থ্রেডেড ল্যাঙ্গুয়েজ, এর মানে হলো JavaScript-এ শুধু একটা কল স্ট্যাক এবং একটা মেমরি হিপ আছে। হাই লেভেলে, এর মানে JavaScript কোড পড়ে, এক লাইন করে, অর্ডারমেনে, এবং একটি কোড পিস এক্সিকিউট করতে হবে নেক্সট লাইনে যাওয়ার আগে। এটি JavaScript-কে প্রাকৃতিকভাবে সিঙ্ক্রোনাস করে তোলে। কখনও কখনও, আমাদের একটি ওয়ার্কআরাউন্ড প্রয়োজন, আমাদের কোডকে অ্যাসিঙ্ক্রোনাস করার জন্য।
সিঙ্ক্রোনাস কোড বনাম অ্যাসিঙ্ক্রোনাস কোড
এই উদাহরণটি দেখুন।
// synchronous console.log("This will print first") console.log("This will print second") console.log("This will print third");
খুব সিম্পল, ঠিক না? প্রতিটি console.log সাকসেশন-এ প্রিন্ট হবে কারণ JavaScript সেগুলো সাকসেশন-এ এক্সিকিউট করে।
চলুন বলি আমরা চাই লাইন টু লাইন থ্রি থেকে আগে প্রিন্ট হয়? আমরা কীভাবে এসেনশিয়ালি उस console.log কে আউট অফ টার্ন প্রিন্ট করতে পারি? আমরা এটি setTimeout()-এ দিয়ে করতে পারি:
// setTimeout console.log("This will print first") setTimeout(() => { console.log("This will print third") }, 1000); console.log("This will print second");
setTimeout() আমাদের একটি JavaScript ফাংশন এক্সিকিউট করতে দেয় থ্রেড ব্লক না করে যাতে অন্য কোড চলে। প্রথম আর্গুমেন্ট হলো কলব্যাক ফাংশন যা একটি সেট করা পরিমাণ টাইমের পর চলে (দ্বিতীয় আর্গুমেন্ট)। দ্বিতীয় আর্গুমেন্ট মিলিসেকেন্ডের সংখ্যা হিসেবে রিপ্রেজেন্ট করা হয়।
এই setTimeout() মেথড অন্যান্য ল্যাঙ্গুয়েজের নেটিভ sleep মেথডকে এইরকম মিমিক করে:
- JavaScript ইঞ্জিন
setTimeout()ফাংশন এক্সিকিউট করলে ব্যাকগ্রাউন্ডে একটি টাইমার সেট করে - টাইমার তার কাউন্টডাউন করলে অন্য কোড চালিয়ে যায়
- টাইমার জিরো হলে
setTimeout()-এ কলব্যাক ফাংশন এক্সিকিউট করে।
setTimeout() কীভাবে কাজ করে তা বোঝা অত্যন্ত গুরুত্বপূর্ণ Promise এবং async/await ফাংশন বোঝার জন্য। আমরা এখন Promise কভার করব।
Promises
একটি Promise তৈরি করা
Promises হচ্ছে অ্যাসিঙ্ক্রোনাস লজিক পারফর্ম করার একটি উপায়। Promise কনস্ট্রাক্টর একটি কলব্যাক ফাংশন নেয় যাতে দুটি প্যারামিটার থাকে: resolve এবং reject। এই কলব্যাক ফাংশনে লজিক থাকে যা, একবার ফিনিশ হলে, একটি রেসপন্স পাস করে resolve বা reject ফাংশন ইনভোক করবে।
console.log("before promise") let promise = new Promise((resolve, reject) => { let resolvedFlag = false; //এটি শুধু একটি ফ্ল্যাগ যাতে আমরা ইন্টেনশনালি রেসপন্স থ্রো করতে পারি লজিক টেস্ট করতে console.log("first"); console.log("second") console.log("third") console.log("fourth"); resolvedFlag = true; //রেজলভডকে true ফ্লিপ করুন একবার সব কনসোল লগ হলে if(resolvedFlag) { //যদি resolved true হয় resolve ফাংশন ইনভোক করুন resolve("Promise resolved"); console.log("after promise"); } else { // অন্যথায় reject ফাংশন ইনভোক করুন একটি নতুন Error অবজেক্টের সাথে মেসেজ reject(new Error("Promise failed")); console.log("after promise"); } });
এই কোড স্নিপেটটি একটি সিম্পল প্রমিস ডেমো করে। Promises তিনটি স্টেটে থাকতে পারে:
- pending - না resolved, না rejected - এটি প্রমিসের ইনিশিয়াল স্টেট
- resolved - সফল এক্সিকিউশন
- rejected - এক্সিকিউশনে এরর
উপরের কোড স্নিপেটে resolvedFlag-কে true থেকে false-এ টগল করে চেষ্টা করুন একটি resolved promise এবং একটি rejected promise-এর রেজোলিউশন ডেমো করতে।
মূল কথা মনে রাখতে হবে: এই Promise একটি ফাংশন ধারণ করে যা স্ক্রিপ্টের এক্সিকিউশন পজ করে যতক্ষণ না Promise resolved বা rejected হয়। তারপর স্ক্রিপ্ট রিজিউম হয়।
একটি Promise রেসপন্স ব্যবহার করা
যখন আমরা একটি Promise-এর ইনস্ট্যান্স ইনিশিয়েট করি, আমরা then() এবং catch() ব্যবহার করি যেই লজিক আমরা প্রমিস থেকে রেসপন্স পাওয়ার পর ব্যবহার করতে চাই তা লে আউট করতে। এটি লে আউট করা হয় এক স্টেটমেন্ট হিসেবে - হাই লেভেল ওভারভিউ দেখে এইরকম:
promise.then(func).catch(func);
then এবং catch মেথড ইনভোক করার প্যারেনথেসিসে একটি ಅನোনিমাস ফাংশন থাকে যাতে রেসপন্স প্যারামিটার হিসেবে পাস করা হয়।
promise // আমরা উপরের কোড স্নিপেটে তৈরি 했던 প্রমিস .then(response => { // সফল রেসপন্স হলে এখানে হিট করে // সফল রেসপন্সে হоне वाली লজিক console.log(response); console.log("after promise"); }) .catch(error => { // যেকোনো এরর এখানে ক্যাচ করে। // এরর রেসপন্সে হোন वाली লজিক console.log(error.message); console.log("after promise"); })
Promises প্রায়শই ডেটাবেস কল করার সময় বা HTTP রিকোয়েস্ট করার সময় ব্যবহার হয়।
Async/Await ফাংশন
sleep() মেথড সিমুলেট করার ফাইনাল উপায় হলো async/await ফাংশন ব্যবহার করা। এসেনশিয়ালি, এই অ্যাসিঙ্ক্রোনাস ফাংশনগুলো শুধু একই লজিক কনস্ট্রাক্ট করার আরেকটি উপায় যেটি আমরা Promise-এ ব্যবহার করতাম, কিন্তু কম কোডে।
async টার্ম প্রি-ES6 ফাংশনে function কীওয়ার্ডের আগে রাখা হয়, এবং ES6+ ফাংশনে প্যারামিটারগুলোর আগে। আপনি যেই লজিক আগে করতে চান সেটি এই কোড ব্লকে রাখতে হয়।
const firstFunction = () => { // লজিক যা আপনি অ্যাসিঙ্ক্রোনাসলি করতে চান let resolved = true; if(resolved) { let respObj = { message: "Resolved!"}; return respObj.message; } else { let errObj = { message: "Error!"}; return errObj.message; } } const asyncExample = async () => { // প্যারামিটারগুলোর যেনে async কীওয়ার্ড console.log("Calling function..."); let result = await firstFunction(); // await যে ফাংশনে আপনার লজিক আছে তার ইনভোকেশনের আগে যায়। // নেক্সট লাইনে যাবে না যতক্ষণ না ফাংশনটি ডন হয়। console.log(result); return result; } asyncExample() // async/await ফাংশন ইনভোক করে
async/await ফাংশন ব্যবহার করলে ভার্চুয়ালি সেম অ্যাসিঙ্ক্রোনাস প্রমিস-বেসড প্রসেস ফলাফল আসে কিন্তু কম কোডে।
উপসংহার
এই আর্টিকেলে আমরা দেখেছি sleep() ফাংশন মিমিক করার উপায়গুলো যা অন্যান্য প্রোগ্রামিং ল্যাঙ্গুয়েজে নেটিভ। আমরা setTimeout() ব্যবহার করেছি অ্যাসিঙ্ক্রোনাস JavaScript ফাংশনların কনসেপ্ট ডেমো করতে যাতে আমরা Promise এবং async/await ফাংশনগুলো দেখতে পারি।