জাভাস্ক্রিপ্ট টিউটোরিয়াল-শিখুন গল্পে গল্পে সাথে 1100+ Exercise

  • জাভাস্ক্রিপ্ট পরিচিতি-Introduction to JavaScript
  • প্রোগ্রামিং শুরু করতে কতটুকু গণিত লাগে?
  • প্রোগ্রামিং শুরু করতে কতটুকু ইংরেজি জানা লাগে?
  • ভালো প্রোগ্রামার কিভাবে হবো? [+৭টি গুরুত্বপূর্ণ টিপস]
  • তিন লেয়ারের JSON শাসন
  • Promise রক্ষাকারী প্রেমিক
  • fetch-এর প্যাঁচ
  • ক্র্যাশ খাইছে CRUD
  • try করে catch কর
  • Async আর Await-এর ভাজা মাছ

Promise রক্ষাকারী প্রেমিক


কমবয়সি পোলাপান প্রেম করতে গিয়ে খেয়ে না খেয়ে ডজনে ডজনে প্রমিজ করতে থাকে। যেমন: ‘আজীবন তোমার সাথে থাকব’, ‘তোমাকে হাতি ঘোড়া কিনে দিব’, ‘কখনো তোমাকে দুঃখ দিব না’, ‘দুই ডজন বাচ্চাকাচ্চা দিব’ ইত্যাদি। কিন্তু বাস্তবে কি সবাই তাদের দেয়া প্রতিশ্রুতি রাখতে পারে?


উত্তর হচ্ছে, সবাই পারে না। কেউ কেউ পারে, আবার কেউ কেউ বলে– আমার ফ্যামিলি মানবে না, বড় ভাইয়ের বিয়ে হওয়ার আগে কিছুই বলতে পারব না। এইসব হাবিজাবি বলে কেটে পড়ে। 


তবে কোনো কিছুর প্রমিজ করার বিষয়টা একটু খেয়াল করলে বুঝতে পারবি– প্রমিজ হচ্ছে ফিউচারে কিছু একটা করবে, সেটার প্রতিশ্রুতি। তাই প্রমিজ করার সাথে সাথে ইমিডিয়েটলি কাজটা হবে না; রবং ফিউচারে কখনো এইটা ফুলফিল করার সময় আসবে। তাই যখন কেউ প্রমিজ করে, তখন সেটা pending অবস্থায় থাকে। 


এই pending অবস্থার পরে হয়তো তুই প্রমিজটা পূরণ করবি। এটাকে বলে প্রমিজ resolve করা। আবার তুই প্রমিজ ভুলেও যেতে পারিস বা ধোঁকা দিতে পারিস, এটাকে বলে প্রমিজ reject করা।

  

অর্থাৎ একটা প্রমিসে তিনধরনের অবস্থা (state) থাকে—


১) যে মুহূর্তে তুই ওয়াদাটা করতেছস, তখন প্রমিজ pending অবস্থায় থাকে। 

২) ফিউচারে তুই ওয়াদা ফুলফিল করতে পারস। প্রমিজ resolve করতে পারস। যেমন চাকরি হয়ে যাওয়ার পর সত্যি সত্যি বিয়ে করলি। সুদিন ফেরত পাওয়ার পর তাকে ছেড়ে চলে গেলি না। তার সাথেই জীবন কাটালি।

৩) অথবা ওয়াদাটা পরিপূর্ণ করলি না, প্রমিজ reject করে দিবি। 


ধর, তুই একটা রেস্টুরেন্টে খাবার অর্ডার দিলি। এখন খাবার আসতে কিছু সময় লাগবে, মানে এটা Pending স্টেটে আছে। তার কিছুক্ষণ পরে তারা তোকে খাবার খেতে দিলে অর্ডার resolve হবে। আর যদি বলে, ভাই রুই মাছ নাই, সব খাবার শেষ। তাহলে তারা প্রমিজ রিজেক্ট করে দিছে। 


Promise

জাভাস্ক্রিপ্টে Promise নামে একটা অবজেক্ট আছে। একটু আগে যেভাবে বলছিলাম, একজাক্টলি এইভাবেই কাজ করে। নিচে new Promise দিয়ে একটা প্রমিজ তৈরি করতেছি। 


এই প্রমিজ ক্রিয়েট করার সময় একটা ফাংশন দিতে হয় প্যারামিটার হিসেবে। বলতে পারস, একটা কলব্যাক ফাংশন দিতে হয়। সেই ফাংশনে দুইটা প্যারামিটার নেয়। প্যারামিটার দুইটাই কিন্তু ফাংশন। 


এদের একটার নাম হচ্ছে resolve, আরেকটার নাম হচ্ছে reject। আর নাম দেখেই বুঝা যাচ্ছে, প্রমিজ যদি ফুলফিল হয়, তাহলে resolve নামক কলব্যাক ফাংশনকে কল করবে। আর যদি প্রমিজ ফুলফিল করতে না পারে, তখন reject ফাংশনকে কল করবে। নিচের কোড দেখলেই বুঝতে পারবি।

 

আর resolve বা reject ফাংশন দুইটাকে কল করার সময় তুই কিছু ডাটা বা তথ্য দিয়ে দিতে পারবি। যেমন, নিচে দুইটার মধ্যেই কিছু ডাটা টেক্সট/স্ট্রিং হিসেবে দিয়ে দিছি। 


  const orderFood = new Promise((resolve, reject) => {
    const foodReady = true   
    if (foodReady) {
      resolve("Food is ready!");
    } else {
      reject("Baap er hotel bondo."); 
    }
  });


যখন তুই new Promise() দিয়ে একটা প্রমিজ বানাবি, সে একটা "Promise অবজেক্ট" রিটার্ন করে। সেই অবজেক্টে অনেকগুলা মেথড থাকে। একটার পর একটা দরকার অনুসারে কল করতে পারবি। সাধারণত তিনটা মেথড ইউজ করা হয়। তাদের নাম then, catch, finally । 


  promise.then().catch().finally()


.then() চলে, যখন প্রমিজ resolve হয়।

.catch() চলে, যখন প্রমিজ reject হয়। 

.finally() প্রমিজ resolve হোক বা reject হোক, .finally() চলবেই।


এদের প্রত্যেকটা আবার প্যারামিটার হিসেবে একটা করে কলব্যাক ফাংশন নেয়। আবার চাইলে একাধিক then ইউজ করাও যায়। 


  promise
    .then( () => { } )
    .catch( () => { } )
    .finally( () => { } )


আমি জাস্ট সিম্পলভাবে একটা then, তারপর একটা catch ইউজ করতেছি। 


  orderFood
    .then((message) => {
      console.log(message); 
    })
    .catch((error) => {
      console.log(error); 
    });

Output: Food is ready!




এই জন্য orderFood কল করার পর সাথে সাথে .then দিছস। আর .then-এর ভিতরে একটা ফাংশন। সেখানে একটা প্যারামিটার আছে message নামে। তুই চাইলে অন্য নামও দিতে পারতি। তারপর ঠিকঠাকমতো ডাটা পেলে কী করবি, তাই এইখানে করবি। আমরা আপাতত ডাটা message কনসোল লগ করতেছি। 


.then-এর কাজ শেষ হলে ঠিক সিমিলারভাবেই .catch()-কে কল করবি। এইটার ভিতরেও একটা ফাংশন থাকবে। এই ফাংশনেও প্যারামিটার থাকবে। সাধারণত মানুষ এই প্যারামিটারের নাম error দেয়। তুই চাইলে অন্য নামও দিতে পারস এবং প্রমিজ রিজেক্টেড হলে, অর্থাৎ ডাটা না দিলে যা যা করতে চাস, তার সব এইখানে করবি। আমরা আপাতত সিম্পলভাবে এররটা কনসোল লগ করে দিচ্ছি।


এখন আমার উদ্দেশ্য হচ্ছে প্রমিজ লিখব। এই প্রমিজ যখন resolve করবে, তখন রিটার্ন হিসেবে একটা অ্যারে পাবে, সেখানে অনেকগুলা ইউজারের নাম থাকবে। আর যদি reject করে, তখন বলবে, কোনো ইউজারের ডাটা নাই। 


  const getUsers = new Promise((resolve, reject) => {
    const usersAvailable = true;
    const users = ["John", "Alice", "Bob", "Charlie"];

    if (usersAvailable) {
      resolve(users);
    } else {
      reject("No user data available.");
    }
  });

  getUsers
    .then((userNames) => {
      console.log(userNames);
    })
    .catch((error) => {
      console.log(error);
    });

Output: ['John', 'Alice', 'Bob', 'Charlie']


কেন প্রমিজ দরকার?

জাভাস্ক্রিপ্ট single-threaded মানে একই সময়ে একটা কাজ করতে পারে। কিন্তু অনেক কাজ আছে, যা সাথে সাথে হয় না, যেমন সার্ভার থেকে ডাটা নিয়ে আসা, ফাইল পড়া ইত্যাদি। এই কাজগুলো ব্লক না করে প্রমিজ ব্যবহার করে অ্যাসিনক্রোনাস হ্যান্ডেল করে। আর প্রমিজ যে সব সময় ভালোভাবে কাজ করবে, সেটার কোনো গ্যরান্টি নাই। তাই Resolve আর Reject দুইটার জন্যই কোড লিখে রাখতে হয়।


সব প্রমিজ উড়ায় ফেলব

অনেক সময় এমন হয় যে, তুই একসাথে একাধিক প্রমিজ নিয়ে কাজ করতে চাস। যেমন ধর, একবারে তিনটা API রিকোয়েস্ট মারবি আর চাইবি সবগুলা রেসপন্স একসাথে চলে আসুক অথবা তিনটা টাস্ক করবি, যেগুলা একসাথে শুরু হবে, কিন্তু কোনটা আগে শেষ হবে, সেটা তুই জানস না।


এক্ষেত্রে Promise.all() একসাথে অনেকগুলা প্রমিজ চালায় এবং সবগুলা প্রমিজ resolve হলে একটা array রিটার্ন করে।


সিম্পলভাবে সব প্রমিজ success হলে resolve হবে, আর একটাও fail করলে reject হয়ে যাবে।


  const moneyRequest = new Promise((resolve, reject) => {
    setTimeout(() => resolve("Request submitted!"), 1000);
  });

  const transferMoney = new Promise((resolve, reject) => {
    setTimeout(() => resolve("Money transferred!"), 2000);
  });

  const payFee = new Promise((resolve, reject) => {
    setTimeout(() => resolve("Fee paid!"), 1500);
  });

  Promise.all([moneyRequest, transferMoney, payFee])
    .then((results) => {
      console.log(results);
    })
    .catch((error) => {
      console.log("Error: ", error);
    });

Output:
["Request submitted!", "Money transferred!", "Fee paid!"]


Practice: 



  1. একটা প্রমিজ লিখে ফেল। এই প্রমিজ যখন resolve করবে, তখন রিটার্ন হিসেবে একটা অ্যারে পাবে, সেখানে অনেকগুলা ইউজারের নাম থাকবে। আর যদি reject করে, তখন রিটার্ন করে, কোন ইউজারের ডাটা নাই। 
  2. তুই একটা পেমেন্ট প্রসেস করার প্রমিজ বানা। সেখানে amount নামে একটা ভেরিয়েবল থাকবে। এই ভেরিয়েবলের মান পজিটিভ হলে (0 এর বেশি হলে) প্রমিজ সফলভাবে প্রসেস হবে। আর যদি এমাউন্টের মান 0 বা তার কম হলে প্রমিজ reject হবে।
  3. এখন sendEmail নামে একটা ফাংশন বানিয়ে ফেল। সেই ফাংশনের ভিতরে একটা প্রমিজ বানিয়ে ফেলবি এবং সেই প্রমিজকে রিটার্ন করবি। এই ফাংশন একটা প্যারামিটার নিবে। প্যারামিটার হিসেবে একটা ই-মেইল নিবি এবং প্রমিজের ওপরে সেই ফাংশনের ভিতরে validEmail-এর একটা অ্যারে থাকবে। যে ই-মেইল প্যারামিটার হিসেবে পাঠানো হয়েছে, সেটা যদি validEmail-এর অ্যারের মধ্যে থাকে, তাহলে প্রমিজ resolve করে বলে দিবে, Email from Nigerian prince। আর যদি ইমেইল এড্রেস validEmail-এর মধ্যে না পায়, তাহলে বলে দিবে, Lets Dance in the spam folder।


Previous PageNext Page