JavaScript async/await প্যাটার্ন যা আপনার জানা উচিত
অ্যাসিঙ্ক্রোনাস প্রোগ্রামিং আধুনিক JavaScript-এর একটি মূল অংশ, এবং async/await এটিকে অনেক বেশি পাঠযোগ্য করে তুলেছে। তবে অনেক ডেভেলপার এখনও সাধারণ সমস্যাগুলোতে আটকে যান: unhandled promise rejections, ধীর sequential requests, বা বিভ্রান্তিকর error handling। এই নিবন্ধে, আমরা ব্যবহারিক async/await প্যাটার্নগুলো explore করব যা আপনি সাথে সাথে প্রয়োগ করে আরও পরিচ্ছন্ন ও দক্ষ কোড লিখতে পারবেন।
1. মৌলিক async/await সিনট্যাক্স
একটি async function সর্বদা একটি Promise রিটার্ন করে। await কীওয়ার্ডটি Promise settle হওয়া পর্যন্ত execution থামিয়ে রাখে, তারপর তার resolved value রিটার্ন করে। যদি Promise reject হয়, এটি একটি error throw করে যা আপনি try/catch দিয়ে catch করতে পারেন।
async function fetchData() {
try {
const response = await fetch('/api/data');
const data = await response.json();
return data;
} catch (error) {
console.error('Fetch failed:', error);
}
}
এটি মূল ভিত্তি। কিন্তু বাস্তব-জগতের পরিস্থিতিতে প্রায়শই আরও সূক্ষ্ম পদ্ধতির প্রয়োজন হয়।
2. সুন্দরভাবে error handling
async/await-এর সবচেয়ে বড় সুবিধাগুলোর একটি হলো আপনি synchronous এবং asynchronous উভয় error-এর জন্য try/catch ব্যবহার করতে পারেন। তবে, একটি try block-এ একাধিক await call-এর ক্ষেত্রে সতর্ক থাকুন: যদি প্রথমটি fail করে, পরবর্তীগুলো execute হবে না।
আরও ভালো granularity-র জন্য, আপনি প্রতিটি await-কে নিজস্ব try/catch-এ wrap করতে পারেন বা পুনরাবৃত্তিমূলক try/catch block এড়াতে একটি helper function ব্যবহার করতে পারেন।
async function getUser(id) {
try {
const user = await fetchUser(id);
return user;
} catch (error) {
console.error('Failed to fetch user:', error);
throw error;
}
}
3. সমান্তরালে promises চালানো
একাধিক স্বাধীন promise sequentially await করা একটি সাধারণ performance ভুল। যদি আপনার একাধিক source থেকে result প্রয়োজন হয়, তাহলে সেগুলো concurrently চালানোর জন্য Promise.all() ব্যবহার করুন।
// Sequential: slow
const user = await fetchUser();
const posts = await fetchPosts();
// Parallel: fast
const [user, posts] = await Promise.all([fetchUser(), fetchPosts()]);
যখন আপনি সব promise settle হওয়ার জন্য অপেক্ষা করতে চান, সেগুলো resolve হোক বা reject, তখন Promise.allSettled() ব্যবহার করুন। এটি তখন উপযোগী যখন আপনি কিছু fail হলেও result সংগ্রহ করতে চান।
4. যখন ক্রম গুরুত্বপূর্ণ তখন sequential execution
কখনও কখনও আপনার item-গুলো ক্রম অনুসারে process করতে হয়, যেমন যখন প্রতিটি step পূর্ববর্তীটির উপর নির্ভর করে। সেক্ষেত্রে, forEach-এর পরিবর্তে await সহ একটি for...of loop ব্যবহার করুন (যা async callback-এর জন্য অপেক্ষা করে না)।
for (const item of items) {
await processItem(item);
}
যদি আপনার concurrency সীমিত করতে হয়, তাহলে p-limit-এর মতো লাইব্রেরি বিবেচনা করুন বা একটি সাধারণ queue implement করুন।
5. loop-এ async/await-এর ফাঁদ এড়ানো
Array.prototype.forEach-এর ভিতরে await ব্যবহার করা একটি ক্লাসিক ভুল: forEach async callback-এর জন্য await করে না, তাই promise resolve হওয়ার আগেই loop শেষ হয়ে যায়। সর্বদা for...of বা Promise.all সহ map ব্যবহার করুন।
6. timeout সহ async/await
Hanging request প্রতিরোধ করতে, আপনি একটি promise-কে timeout-এর বিরুদ্ধে race করতে পারেন।
function timeout(ms) {
return new Promise((_, reject) =>
setTimeout(() => reject(new Error('Timeout')), ms)
);
}
await Promise.race([fetchData(), timeout(5000)]);
এই প্যাটার্নটি এমন API call-এর জন্য উপযোগী যা hang করতে পারে।
7. Async generators এবং for await...of
Async generator আপনাকে asynchronously value-এর stream তৈরি করতে দেয়। আপনি for await...of দিয়ে সেগুলো consume করতে পারেন।
async function* fetchPages() {
let page = 1;
while (true) {
const data = await fetch(`/api/items?page=${page}`);
if (data.length === 0) break;
yield data;
page++;
}
}
for await (const page of fetchPages()) {
console.log(page);
}
এটি paginated API বা streaming data-এর জন্য দুর্দান্ত।
8. সাধারণ ভুল এবং সেগুলো এড়ানোর উপায়
- await করতে ভুলে যাওয়া: await ছাড়া একটি async function call করলে একটি Promise রিটার্ন হয়, এবং error unhandled থেকে যেতে পারে।
- non-async function-এ await ব্যবহার: Syntax error। সর্বদা function-টিকে async হিসেবে চিহ্নিত করুন।
- অতিরিক্ত sequential await ব্যবহার: সম্ভব হলে Promise.all ব্যবহার করুন।
- Rejection handle না করা: সর্বদা .catch বা try/catch যোগ করুন।
9. পরিচ্ছন্ন async কোডের জন্য সেরা অনুশীলন
- পাঠযোগ্যতার জন্য raw Promise-এর চেয়ে async/await পছন্দ করুন।
- স্বাধীন operation-এর জন্য Promise.all ব্যবহার করুন।
- উপযুক্ত স্তরে error handle করুন।
- async function ছোট এবং focused রাখুন।
- loop-এ সতর্কতার সাথে async/await ব্যবহার করুন; সঠিক প্যাটার্ন বেছে নিন।
FAQ
async/await এবং Promise-এর মধ্যে পার্থক্য কী?
Async/await হলো Promise-এর উপর syntactic sugar, যা asynchronous কোডকে synchronous-এর মতো দেখায়। এটি chaining এবং try/catch দিয়ে error handling সহজ করে।
আমি কি forEach loop-এর ভিতরে await ব্যবহার করতে পারি?
না, forEach async callback-এর জন্য অপেক্ষা করে না। পরিবর্তে for...of বা map সহ Promise.all ব্যবহার করুন।
কীভাবে একাধিক async operation সমান্তরালে চালাব?
সেগুলো concurrently চালাতে এবং সব resolve হওয়ার জন্য অপেক্ষা করতে Promise.all() ব্যবহার করুন।
JSON API-এর সাথে কাজ করার সময়, আপনি আমাদের JSON Formatter ব্যবহার করে দ্রুত response format এবং validate করতে পারেন।