Promise ES6 (ECMAScript 2015)-এ এক নতুন ফিচার হিসেবে পরিচিত, যা অ্যাসিঙ্ক্রোনাস কোডের কার্যপ্রণালী আরও সহজ, পড়নযোগ্য এবং পরিচালনাযোগ্য করে তোলে। প্রমিজের মাধ্যমে asynchronous কাজগুলো সিঙ্ক্রোনাস ভাবে লেখা সম্ভব হয়, ফলে callback hell বা nested callbacks থেকে মুক্তি পাওয়া যায়।
ES6 এ Promise API আরও উন্নত হয়েছে এবং কিছু নতুন ফিচার যুক্ত হয়েছে, যার মাধ্যমে promises আরো শক্তিশালী এবং সহজে ব্যবহৃত হতে পারে।
Promise: Advanced Concepts
প্রমিজের advanced ব্যবহারগুলোতে কিছু নতুন মেথড এবং কমপ্লেক্স অপারেশন অন্তর্ভুক্ত রয়েছে, যেগুলি প্রমিজের কার্যক্ষমতা এবং ব্যবহারের সুবিধা বাড়ায়।
1. Promise Chaining
প্রমিজের সবচেয়ে শক্তিশালী বৈশিষ্ট্য হল chaining। আপনি একাধিক then() ব্যবহার করে একের পর এক asynchronous কাজ সম্পন্ন করতে পারেন, এবং প্রতিটি then() একটি নতুন প্রমিজ ফেরত দেয়, যার ফলে চেইনিং সম্ভব হয়।
Promise Chaining উদাহরণ
function fetchData(url) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = { id: 1, name: "John Doe" };
resolve(data); // ফেক ডেটা রিটার্ন করছি
}, 1000);
});
}
fetchData("https://api.example.com/user")
.then(data => {
console.log("Data fetched:", data);
return data.name; // আমরা পরবর্তী then এ name পাঠাচ্ছি
})
.then(name => {
console.log("Name:", name);
})
.catch(error => {
console.log("Error:", error);
});
এখানে, then() মেথডটি প্রতিটি স্তরে asynchronous কাজ সম্পন্ন করতে ব্যবহার করা হয়েছে এবং পরবর্তী then() মেথডে প্রাপ্ত ডেটা পাঠানো হয়েছে। catch() মেথডটি কোনো ভুল (error) ধরতে ব্যবহৃত হয়েছে।
2. Promise.all()
Promise.all() একাধিক প্রমিজকে একসঙ্গে সামলাতে ব্যবহার করা হয়। এটি একটি অ্যারে নেয়, যার মধ্যে একাধিক প্রমিজ থাকে, এবং সবগুলো প্রমিজ সফলভাবে সম্পন্ন হলে একটি নতুন প্রমিজ রিটার্ন করে। যদি কোনো একটি প্রমিজ ভুল (reject) হয়, তাহলে পুরো Promise.all() রিজেক্ট হয়ে যাবে।
Promise.all() উদাহরণ
const promise1 = new Promise((resolve, reject) => setTimeout(resolve, 1000, 'First'));
const promise2 = new Promise((resolve, reject) => setTimeout(resolve, 2000, 'Second'));
const promise3 = new Promise((resolve, reject) => setTimeout(resolve, 3000, 'Third'));
Promise.all([promise1, promise2, promise3])
.then(results => {
console.log(results); // ["First", "Second", "Third"]
})
.catch(error => {
console.log("Error:", error);
});
এখানে, Promise.all() তিনটি প্রমিজের জন্য কাজ করছে এবং প্রত্যেকটি প্রমিজ সফল হলে results আউটপুট করবে।
3. Promise.race()
Promise.race() মেথড একাধিক প্রমিজের মধ্যে প্রথমে যেটি সম্পন্ন হবে, সেটি রিটার্ন করে। যেহেতু race() প্রথম প্রমিজকে ফেরত দেয়, তাই যদি প্রথম প্রমিজটি রিজেক্ট হয়, তখন অন্যান্য প্রমিজগুলো চলতে থাকলেও পুরো race() প্রমিজ রিজেক্ট হয়ে যাবে।
Promise.race() উদাহরণ
const promise1 = new Promise((resolve, reject) => setTimeout(resolve, 2000, 'First'));
const promise2 = new Promise((resolve, reject) => setTimeout(resolve, 1000, 'Second'));
Promise.race([promise1, promise2])
.then(result => {
console.log(result); // "Second"
})
.catch(error => {
console.log("Error:", error);
});
এখানে, Promise.race() দ্রুততম প্রমিজটির ফলাফল রিটার্ন করবে, অর্থাৎ promise2 প্রথমে সম্পন্ন হওয়ার কারণে "Second" রিটার্ন হয়েছে।
4. Promise.allSettled()
Promise.allSettled() মেথডটি সব প্রমিজের অবস্থা জানায়, whether resolved or rejected। এটি all promises এর সাথে কাজ করে এবং প্রত্যেকটি প্রমিজের ফলাফল (success বা failure) সম্পর্কে একটি রিপোর্ট দেয়। এটি all() এর মতো কাজ করে না, কারণ এটি সব প্রমিজের ফলাফলকেই সংগ্রহ করে, ভিন্নভাবে race() এর মতোও নয়, যেখানে প্রথম প্রমিজের ফলাফল দ্রুত পাওয়ার চেষ্টা করা হয়।
Promise.allSettled() উদাহরণ
const promise1 = new Promise((resolve, reject) => setTimeout(resolve, 1000, 'Success 1'));
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 1500, 'Error 1'));
const promise3 = new Promise((resolve, reject) => setTimeout(resolve, 2000, 'Success 2'));
Promise.allSettled([promise1, promise2, promise3])
.then(results => {
console.log(results);
// [
// { status: 'fulfilled', value: 'Success 1' },
// { status: 'rejected', reason: 'Error 1' },
// { status: 'fulfilled', value: 'Success 2' }
// ]
});
এখানে, Promise.allSettled() সব প্রমিজের ফলাফল জানাচ্ছে, যে কোন প্রমিজ সফলভাবে সম্পন্ন হলে তার মান দেখাচ্ছে এবং যদি কোনো প্রমিজ ভুল হয়, তাহলে তার কারণে ব্যর্থতার কারণে reason দেয়া হচ্ছে।
5. Async/Await with Promises
Async/Await ES8 (ECMAScript 2017)-এ অন্তর্ভুক্ত হলেও এটি Promise API এর সাথে খুবই শক্তিশালীভাবে কাজ করে। async ফাংশন Promise ফেরত দেয় এবং await মেথড একটি প্রমিজের সম্পন্ন হওয়া পর্যন্ত অপেক্ষা করে।
Async/Await উদাহরণ
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve('Data received'), 2000);
});
}
async function fetchDataAsync() {
const result = await fetchData();
console.log(result); // "Data received"
}
fetchDataAsync();
এখানে, await ব্যবহৃত হয়েছে যা fetchData() প্রমিজটি সম্পন্ন হওয়ার জন্য অপেক্ষা করবে, এবং পরে result আউটপুট করবে।
সারাংশ
- Promise API আপনাকে অ্যাসিঙ্ক্রোনাস কোডে আরও পরিষ্কার, প্রেডিক্টেবল, এবং মেইনটেনেবল কোড লেখার সুযোগ দেয়।
- Promise এর সাথে chaining,
all(),race(),allSettled()এবং async/await ব্যবহারের মাধ্যমে জটিল অ্যাসিঙ্ক্রোনাস কার্যক্রম সহজে সম্পাদন করা সম্ভব। - এই ফিচারগুলো ব্যবহার করলে callback hell থেকে মুক্তি পাওয়া যায় এবং কোডের পড়নযোগ্যতা বৃদ্ধি পায়।
Promise.all(), Promise.race(), এবং Promise.allSettled() ES6 (ECMAScript 2015)-এ নতুন Promise মেথড হিসেবে অন্তর্ভুক্ত হয়েছে, যা অ্যাসিঙ্ক্রোনাস অপারেশন পরিচালনা করতে সাহায্য করে। এই মেথডগুলোর মাধ্যমে একাধিক Promise একসাথে বা দ্রুততম সফল/অসফল Promise-এর ভিত্তিতে কাজ করা যায়। তারা Promise-based অ্যাসিঙ্ক্রোনাস কোডের সম্পাদনাকে আরও নিয়ন্ত্রণযোগ্য এবং ম্যানেজেবল করে তোলে।
1. Promise.all()
Promise.all() মেথডটি একাধিক Promise একসাথে চালায় এবং তাদের সকল Promise সফল হলে একটি একক Promise ফেরত দেয়, যেখানে সেই Promise এর মান হবে সমস্ত Promise এর মানের অ্যারে। যদি কোন একটি Promise ব্যর্থ হয় (rejected), তবে Promise.all() তৎক্ষণাৎ ব্যর্থ হয় এবং অন্য যেকোনো Promise গুলি তার ফলাফলকে উপেক্ষা করে।
Sintax:
Promise.all([promise1, promise2, promise3])
.then(values => {
// All promises are fulfilled
})
.catch(error => {
// One of the promises is rejected
});
Promise.all() উদাহরণ
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(resolve, 100, 'foo'));
const promise3 = 42;
Promise.all([promise1, promise2, promise3])
.then(values => {
console.log(values); // [3, "foo", 42]
})
.catch(error => {
console.error(error);
});
এখানে, Promise.all() সব Promise গুলির সফল ফলাফল নিয়ে আসবে এবং একটি অ্যারে রিটার্ন করবে যা সব Promise গুলির মান ধারণ করবে। যদি কোন একটি Promise ব্যর্থ হয়, তবে catch() ব্লক কল হবে।
2. Promise.race()
Promise.race() মেথডটি একাধিক Promise এর মধ্যে প্রথমে যেটি সম্পন্ন (fulfilled) বা ব্যর্থ (rejected) হয় সেটি ফিরিয়ে দেয়। এটি যেকোনো এক Promise-এর ফলাফলকে দ্রুত পাওয়ার জন্য ব্যবহার করা হয়। যদি প্রথম Promise সফল হয়, তাহলে সেটি সম্পন্ন হবে, আর যদি প্রথম Promise ব্যর্থ হয়, তবে সেটি ব্যর্থ হবে।
Sintax:
Promise.race([promise1, promise2, promise3])
.then(value => {
// First fulfilled promise
})
.catch(error => {
// First rejected promise
});
Promise.race() উদাহরণ
const promise1 = new Promise((resolve, reject) => setTimeout(resolve, 500, 'First'));
const promise2 = new Promise((resolve, reject) => setTimeout(resolve, 100, 'Second'));
const promise3 = new Promise((resolve, reject) => setTimeout(resolve, 200, 'Third'));
Promise.race([promise1, promise2, promise3])
.then(value => {
console.log(value); // "Second"
})
.catch(error => {
console.error(error);
});
এখানে, Promise.race() প্রথমে যে Promise সফল হবে, সেটির মান রিটার্ন করবে। promise2 দ্রুততম Promise ছিল, তাই এটি আগে সম্পন্ন হয়ে তার মান "Second" প্রদান করে।
3. Promise.allSettled()
Promise.allSettled() মেথডটি সমস্ত Promise এর ফলাফল জানিয়ে দেয়, তবে সেটা সফল (fulfilled) হোক বা ব্যর্থ (rejected)। এটি একটি অ্যারে রিটার্ন করে, যেখানে প্রত্যেকটি Promise এর অবস্থা এবং তার মান বা ত্রুটি দেওয়া থাকে। এটি খুব উপকারী যখন আপনি চান যে সব Promise গুলি শেষ হোক, এবং প্রত্যেকটির ফলাফল বা ত্রুটি দেখতে চান।
Sintax:
Promise.allSettled([promise1, promise2, promise3])
.then(results => {
// Array of results (fulfilled or rejected)
});
Promise.allSettled() উদাহরণ
const promise1 = Promise.resolve(42);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'Error'));
const promise3 = new Promise((resolve, reject) => setTimeout(resolve, 200, 'Success'));
Promise.allSettled([promise1, promise2, promise3])
.then(results => {
console.log(results);
// [
// { status: "fulfilled", value: 42 },
// { status: "rejected", reason: "Error" },
// { status: "fulfilled", value: "Success" }
// ]
});
এখানে, Promise.allSettled() সমস্ত Promise এর ফলাফল দেখাবে, তারা সফল হলে value এবং ব্যর্থ হলে reason প্রদান করবে। এটি খুবই কার্যকর যখন আপনি চান যে সব Promise গুলি শেষ হোক, এবং ফলাফল বা ত্রুটি দেখতে চান।
সারাংশ
Promise.all(): সমস্ত Promise সফল হলে একক Promise ফেরত দেয়। যদি কোন একটি Promise ব্যর্থ হয়, তখন তা পুরোপুরি ব্যর্থ হবে।Promise.race(): যে Promise প্রথমে সম্পন্ন হবে (সফল বা ব্যর্থ), সেটি ফিরিয়ে দেয়।Promise.allSettled(): সমস্ত Promise এর ফলাফল জানায়, তা সফল বা ব্যর্থ হওয়া সত্ত্বেও।
এই মেথডগুলোকে Promise-based asynchronous কোড এর মধ্যে নিয়ন্ত্রণ এবং কর্মক্ষমতা বৃদ্ধি করতে ব্যবহার করা হয়।
ES6-এ Promise ব্যবহারের মাধ্যমে অ্যাসিঙ্ক্রোনাস অপারেশনগুলো সহজে এবং কার্যকরভাবে পরিচালনা করা সম্ভব। তবে, যখন একাধিক Promise থাকে এবং আপনাকে সবগুলো Promise-এর ফলাফল একসাথে পেতে হয়, তখন কিছু নির্দিষ্ট পদ্ধতি ব্যবহার করা হয়। ES6 এবং পরবর্তী সংস্করণে Promise.all(), Promise.allSettled(), Promise.race(), এবং Promise.any() এর মাধ্যমে একাধিক Promise হ্যান্ডলিং করা যায়।
এখানে, আমরা Multiple Promises হ্যান্ডলিংয়ের বিভিন্ন পদ্ধতি নিয়ে আলোচনা করব।
Promise.all()
Promise.all() একাধিক Promise গুলোকে একসাথে হ্যান্ডল করে এবং একটি নতুন Promise রিটার্ন করে। এটি শুধুমাত্র তখনই fulfilled (সম্পূর্ণ) হবে, যখন সবটি Promise সম্পন্ন হবে। যদি কোনো একটি Promise rejected হয়, তবে পুরো Promise.all() কলটি rejected হয়ে যাবে।
Promise.all() এর ব্যবহার:
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, "First Promise");
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 2000, "Second Promise");
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 3000, "Third Promise");
});
Promise.all([promise1, promise2, promise3])
.then(values => {
console.log(values); // ["First Promise", "Second Promise", "Third Promise"]
})
.catch(error => {
console.log(error);
});
এখানে, Promise.all() তিনটি Promise একসাথে সমাধান করবে এবং তিনটি Promise এর ফলাফল একটি অ্যারেতে রিটার্ন করবে। যদি কোনো Promise rejected হয়, তাহলে catch() ব্লকটি কল হবে।
Promise.all() এর ক্ষেত্রে সতর্কতা:
- যদি কোনো একটি Promise rejected হয়, তবে পুরো
Promise.all()ফাংশন rejected হবে এবং এর সমস্ত resolved ফলাফল উপেক্ষা করা হবে।
Promise.allSettled()
Promise.allSettled() সমস্ত Promise শেষ হবার পর তাদের ফলাফল জানায়, সেটা fulfilled বা rejected যাই হোক না কেন। এটি একটি নতুন Promise রিটার্ন করে এবং প্রত্যেকটি Promise এর ফলাফল একটি অবজেক্ট হিসেবে প্রদান করে যার মধ্যে থাকে:
status:fulfilledবাrejectedvalue: যদি Promise fulfilled হয়, তাহলে ফলাফলreason: যদি Promise rejected হয়, তাহলে ত্রুটি বার্তা
Promise.allSettled() এর ব্যবহার:
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, "First Promise");
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(reject, 2000, "Second Promise failed");
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 3000, "Third Promise");
});
Promise.allSettled([promise1, promise2, promise3])
.then(results => {
results.forEach(result => {
if (result.status === "fulfilled") {
console.log(result.value); // Success
} else {
console.log(result.reason); // Error
}
});
});
এখানে, Promise.allSettled() সব Promise এর ফলাফল (সফল বা ব্যর্থ) দেখাবে। এটি কোনটিকে উপেক্ষা না করে সমস্ত Promise এর ফলাফল প্রাপ্ত করে।
Promise.race()
Promise.race() একাধিক Promise এর মধ্যে যেটি প্রথমে fulfilled অথবা rejected হবে, সেটির ফলাফল রিটার্ন করবে। যদি কোনো Promise প্রথমে rejected হয়, তবে সেটি সবচেয়ে আগে catch ব্লকে চলে যাবে। এই পদ্ধতিতে প্রথম Promise সমাধান হওয়ার পর অন্যগুলোকে আর প্রক্রিয়া করা হয় না।
Promise.race() এর ব্যবহার:
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, "First Promise");
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, "Second Promise");
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 1500, "Third Promise");
});
Promise.race([promise1, promise2, promise3])
.then(result => {
console.log(result); // "Second Promise"
})
.catch(error => {
console.log(error);
});
এখানে, Promise.race() দ্বিতীয় Promise কে fulfilled হিসেবে প্রথম পেয়ে তার ফলাফল রিটার্ন করবে, কারণ এটি দ্রুত শেষ হয়েছে। অন্য Promise গুলোকে উপেক্ষা করা হবে।
Promise.any()
Promise.any() একাধিক Promise এর মধ্যে প্রথম fulfilled Promise এর ফলাফল রিটার্ন করবে। তবে, এটি rejected Promise গুলোকে উপেক্ষা করে, এবং যদি সমস্ত Promise rejected হয়, তাহলে একটি AggregateError প্রদান করবে।
Promise.any() এর ব্যবহার:
const promise1 = new Promise((resolve, reject) => {
setTimeout(reject, 1000, "First Promise failed");
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, "Second Promise");
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(reject, 1500, "Third Promise failed");
});
Promise.any([promise1, promise2, promise3])
.then(result => {
console.log(result); // "Second Promise"
})
.catch(error => {
console.log(error); // AggregateError: All promises were rejected
});
এখানে, Promise.any() প্রথম fulfilled Promise এর ফলাফল রিটার্ন করেছে, আর বাকি rejected Promise গুলোকে উপেক্ষা করেছে। সব Promise rejected হলে, এটি একটি AggregateError ফেলে।
Summary
Promise.all(): সমস্ত Promise সফল হলে একটি ফলাফল প্রদান করে, যদি কোন একটি Promise ব্যর্থ হয়, তবে পুরো সেট ব্যর্থ হয়।Promise.allSettled(): সব Promise এর ফলাফল প্রদান করে, সফল বা ব্যর্থ যাই হোক না কেন।Promise.race(): প্রথমে সম্পন্ন হওয়া Promise এর ফলাফল প্রদান করে, ব্যর্থ হলে অন্যগুলোর ফলাফল উপেক্ষা করে।Promise.any(): প্রথম fulfilled Promise এর ফলাফল প্রদান করে, যদি সমস্ত Promise ব্যর্থ হয়, তবে AggregateError প্রদান করে।
এই পদ্ধতিগুলোর মাধ্যমে আপনি একাধিক Promise অ্যাসিঙ্ক্রোনাস কোড খুব সহজে এবং কার্যকরভাবে হ্যান্ডল করতে পারবেন।
ES6-এ অ্যাসিনক্রোনাস কোড লেখা সহজ করার জন্য বেশ কিছু শক্তিশালী ফিচার যুক্ত করা হয়েছে। এর মধ্যে Promises, async/await, এবং Generator Functions বিশেষভাবে গুরুত্বপূর্ণ। এগুলোর মাধ্যমে আপনি অ্যাসিনক্রোনাস কোড আরও সহজে, কার্যকরভাবে এবং পরিচালনাযোগ্যভাবে লিখতে পারেন।
1. Promises
Promise এক ধরনের অবজেক্ট যা ভবিষ্যতে একটি মান (value) প্রদান করবে, এবং এটি সফলভাবে সম্পন্ন হলে (resolved) বা কোনো সমস্যা হলে (rejected) একটি ফলাফল ফেরত দেয়। এটি callback hell (অনেক নেস্টেড কলব্যাকের সমস্যা) থেকে রক্ষা পেতে সহায়তা করে এবং কোডকে আরও পরিষ্কার করে।
Promise এর মেথড:
then(): Promise সফলভাবে সম্পন্ন হলে কলব্যাক ফাংশন চালানো হয়।catch(): Promise যদি ব্যর্থ হয় (rejected), তাহলে এটি একটি এরর হ্যান্ডলার চালায়।finally(): Promise সম্পন্ন হলে (success বা failure যাই হোক) যেকোনো ক্লিনআপ অপারেশন চালাতে ব্যবহার করা হয়।
উদাহরণ:
const fetchData = new Promise((resolve, reject) => {
const success = true; // Test variable
if (success) {
resolve("Data fetched successfully!");
} else {
reject("Failed to fetch data.");
}
});
fetchData
.then((data) => {
console.log(data); // "Data fetched successfully!"
})
.catch((error) => {
console.log(error); // "Failed to fetch data."
})
.finally(() => {
console.log("Request completed."); // Always runs
});
এখানে, then() ব্যবহার করে সফল ফলাফল, catch() দিয়ে ব্যর্থ ফলাফল এবং finally() দিয়ে ক্লিনআপ অপারেশন সম্পাদিত হয়।
2. Async/Await
Async/Await ES6-এ অ্যাসিনক্রোনাস কোড লেখার আরো আধুনিক ও কার্যকর পদ্ধতি। এটি Promise এর উপর ভিত্তি করে কাজ করে, তবে এটি কোডকে আরো সিনক্রোনাস (যেমন সোজা কোডের মতো) দেখায়। async ফাংশনটি একটি Promise রিটার্ন করে এবং await একটি Promise এর রেজাল্ট পাওয়ার জন্য অপেক্ষা করে।
Async/Await এর সুবিধা:
- Readable কোড: Asynchronous কোড আরো সহজভাবে লেখা যায়।
- Error handling:
try/catchব্লকের মাধ্যমে সহজে এরর হ্যান্ডলিং করা যায়।
উদাহরণ:
// Async/Await Example
function fetchData() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("Data fetched!");
}, 2000);
});
}
async function getData() {
try {
const data = await fetchData(); // wait until Promise is resolved
console.log(data); // "Data fetched!"
} catch (error) {
console.log("Error:", error);
}
}
getData();
এখানে, await এর মাধ্যমে fetchData() ফাংশনটির রেজাল্ট পাওয়ার জন্য আমরা অপেক্ষা করছি, এবং try/catch ব্লকের মধ্যে সহজে এরর হ্যান্ডলিং করা হয়েছে।
3. Promise.all() এবং Promise.race()
Promise.all() এবং Promise.race() দুইটি গুরুত্বপূর্ণ Promise কৌশল, যা একাধিক Promise এর সমন্বয়ে অ্যাসিনক্রোনাস কাজগুলো পরিচালনা করতে ব্যবহৃত হয়।
Promise.all():
Promise.all() একাধিক Promise গ্রহণ করে এবং তাদের সবগুলো সফলভাবে পূর্ণ হলে একটি একক Promise রিটার্ন করে। যদি কোনো একটি Promise ব্যর্থ হয়, তাহলে catch() হ্যান্ডলার কল হবে।
উদাহরণ:
const promise1 = new Promise((resolve) => setTimeout(resolve, 1000, "First"));
const promise2 = new Promise((resolve) => setTimeout(resolve, 2000, "Second"));
const promise3 = new Promise((resolve, reject) => setTimeout(reject, 1500, "Error"));
Promise.all([promise1, promise2, promise3])
.then((results) => {
console.log(results); // If all promises are resolved
})
.catch((error) => {
console.log(error); // "Error"
});
এখানে, যদি তৃতীয় Promise reject হয়, তাহলে Promise.all() catch() কল করবে এবং কোনরকম রেজাল্ট রিটার্ন করবে না।
Promise.race():
Promise.race() একাধিক Promise গ্রহণ করে, তবে এটি প্রথমে পূর্ণ হওয়া Promise এর রেজাল্ট ফেরত দেয়। একাধিক Promise একে অপরকে রেসে পরাজিত করে, এবং প্রথম যে Promise সফল হয়, তা ফেরত আসে।
উদাহরণ:
const promise1 = new Promise((resolve) => setTimeout(resolve, 2000, "First"));
const promise2 = new Promise((resolve) => setTimeout(resolve, 1000, "Second"));
Promise.race([promise1, promise2])
.then((result) => {
console.log(result); // "Second"
});
এখানে, promise2 ১ সেকেন্ডে রেজলভ হওয়ায় Promise.race() প্রথমেই তার রেজাল্ট (যা "Second") ফেরত দেয়।
4. Generator Functions এবং Async Iterators
ES6-এ Generator Functions এবং Async Iterators ব্যবহার করে আপনি আরও শক্তিশালী এবং কাস্টমাইজড অ্যাসিনক্রোনাস ফ্লো তৈরি করতে পারেন। Async Generators ফাংশনগুলি অ্যাসিনক্রোনাস ডেটা সরবরাহের জন্য বিশেষভাবে উপযোগী, যেখানে আপনি একাধিক yield এর মাধ্যমে ডেটা প্রক্রিয়া করতে পারেন এবং তার রেজাল্টটি অ্যাসিনক্রোনাসভাবে গ্রহণ করতে পারেন।
উদাহরণ:
async function* fetchData() {
yield await new Promise((resolve) => setTimeout(resolve, 1000, "Data 1"));
yield await new Promise((resolve) => setTimeout(resolve, 2000, "Data 2"));
yield await new Promise((resolve) => setTimeout(resolve, 3000, "Data 3"));
}
(async () => {
for await (let data of fetchData()) {
console.log(data); // "Data 1", "Data 2", "Data 3"
}
})();
এখানে, async generator function একে একে yield করে অ্যাসিনক্রোনাস ডেটা প্রদান করছে, এবং for await লুপের মাধ্যমে ডেটাগুলো ধীরে ধীরে পাওয়া যাচ্ছে।
সারাংশ
ES6-এ Async Control Flow ব্যবস্থাপনার জন্য কয়েকটি শক্তিশালী কৌশল রয়েছে, যার মধ্যে Promises, async/await, Promise.all(), Promise.race(), এবং Async Generators অন্যতম। এই ফিচারগুলো অ্যাসিনক্রোনাস কোড লেখাকে আরও সহজ, পরিষ্কার, এবং পরিচালনাযোগ্য করে তোলে, বিশেষ করে জটিল অ্যাসিনক্রোনাস ফ্লো তৈরি করার সময়। Async/Await কোডকে সিনক্রোনাস স্টাইলে লেখার সুযোগ দেয়, যা অ্যাসিনক্রোনাস কোডকে আরও সহজ এবং ডিবাগgable করে তোলে।
Parallel এবং Concurrent Execution এর মধ্যে পার্থক্য এবং তাদের ব্যবহার ES6 এর নতুন ফিচারগুলি, বিশেষ করে Promises, async/await, এবং Generators ব্যবহার করে বাস্তবায়িত করা যেতে পারে। এই দুটি ধারণা সম্পর্কে কিছু মৌলিক কথা জানার পর, আমরা দেখব কীভাবে ES6 এর ফিচারগুলি ব্যবহার করে এই কাজগুলোকে কার্যকরী করা যায়।
Parallel Execution:
Parallel Execution এর মানে হল একাধিক কাজ একই সময়ে চালানো। এটি তখন ব্যবহার করা হয় যখন আমাদের একাধিক সম্পূর্ণ স্বাধীন কাজ একে অপরের সাথে কোনো সম্পর্ক ছাড়াই একসাথে চলতে পারে।
ES6 এ, Promise ব্যবহার করে একাধিক asynchronous অপারেশনকে একসাথে চালানো সম্ভব হয়।
Parallel Execution Using Promises:
// Simulating two independent API calls
function fetchData1() {
return new Promise((resolve) => {
setTimeout(() => resolve('Data from API 1'), 2000);
});
}
function fetchData2() {
return new Promise((resolve) => {
setTimeout(() => resolve('Data from API 2'), 3000);
});
}
// Parallel execution using Promise.all
Promise.all([fetchData1(), fetchData2()])
.then((results) => {
console.log('Parallel Execution Results:');
console.log(results[0]); // Data from API 1
console.log(results[1]); // Data from API 2
})
.catch((error) => console.error('Error in Parallel Execution:', error));
এখানে, fetchData1() এবং fetchData2() ফাংশন দুটি Promise রিটার্ন করে এবং আমরা Promise.all() ব্যবহার করে একে অপরের উপর নির্ভর না করে একসাথে তাদের ফলাফল পেতে পারি। Promise.all() মেথড একাধিক Promise এর সাথে কাজ করতে সাহায্য করে, এবং সমস্ত Promises সফল হলে তা রিটার্ন হয়।
Concurrent Execution:
Concurrent Execution এর মানে হল একাধিক কাজ একসাথে শুরু হলেও এগুলো কখনো একসাথে সম্পন্ন হয় না। এগুলোর মধ্যে কিছু সময়ের ব্যবধান থাকতে পারে, এবং এগুলোর মধ্যে কিছু কাজ একে অপরের সাথে সমান্তরাল হতে পারে।
Async/Await ব্যবহার করে আমরা সিমুলেট করতে পারি concurrent কার্যকলাপ, যেখানে একাধিক কাজের মধ্যে নির্দিষ্ট সময়ের পার্থক্য থাকে।
Concurrent Execution Using Async/Await:
async function fetchData() {
console.log("Fetching data...");
const result1 = fetchData1(); // API 1
const result2 = fetchData2(); // API 2
// Wait for both promises to resolve concurrently
const data = await Promise.all([result1, result2]);
console.log('Concurrent Execution Results:');
console.log(data[0]); // Data from API 1
console.log(data[1]); // Data from API 2
}
fetchData();
এখানে, fetchData() ফাংশনটি async এবং await এর মাধ্যমে দুইটি API কলকে একসাথে শুরু করেছে। তবে, await ব্যবহার করা হয়েছে Promise.all() এর সাথে, যার মাধ্যমে আমরা একসাথে প্রতিটি API কলের ফলাফল পাওয়ার জন্য অপেক্ষা করছি।
Generators and Asynchronous Programming for Concurrent Execution:
Generators ES6 এর একটি উন্নত ফিচার যা asynchronous programming সহজ করে তোলে। এটি concurrent কাজগুলিকে আরও কার্যকরভাবে সম্পাদন করতে সাহায্য করে, যেখানে আমরা কাজের বিভিন্ন ধাপকে নিয়ন্ত্রণ করতে পারি।
Concurrent Execution Using Generators:
function* fetchConcurrentData() {
const data1 = yield fetchData1();
console.log(data1);
const data2 = yield fetchData2();
console.log(data2);
}
const generator = fetchConcurrentData();
generator.next().value.then((data1) => {
generator.next(data1).value.then((data2) => {
generator.next(data2);
});
});
এখানে, আমরা Generator ফাংশন ব্যবহার করে fetchData1() এবং fetchData2() এর concurrent execution তৈরি করেছি। যদিও এগুলো concurrent হতে পারে, কিন্তু আমরা প্রতিটি ধাপে অপেক্ষা করি এবং next() মেথড ব্যবহার করে একে একে এগুলো চালাই।
Summary of Parallel and Concurrent Execution in ES6
- Parallel Execution: একাধিক asynchronous কাজ একে অপরের সাথে চলতে পারে। এর জন্য Promise.all() ব্যবহার করা হয়।
- Concurrent Execution: একাধিক কাজ একসাথে শুরু হলেও, তারা সমান্তরালভাবে সম্পন্ন হয় না। Async/Await এবং Generators এর মাধ্যমে আমরা concurrent execution সহজে বাস্তবায়ন করতে পারি।
এসব টেকনিক এবং ফিচারগুলি আমাদের কোডকে আরও কার্যকর, পরিষ্কার এবং পারফরম্যান্ট করে তোলে, বিশেষ করে যখন আমাদের একাধিক asynchronous কাজ সমান্তরালে বা পাশাপাশি চালাতে হয়।
Read more