Async/Await হল সিনক্রোনাস স্টাইলে অ্যাসিনক্রোনাস কোড লেখার জন্য একটি জোড়া কীওয়ার্ড, যা Swift-এ iOS 13 থেকে এবং Kotlin-এ করুটিনের সাথে উপলব্ধ। Apple Swift Documentation, 2026 অনুসারে, Async/Await কলব্যাক চেইন এবং GCD প্রতিস্থাপন করে, অ্যাসিনক্রোনাস কোডকে রৈখিক এবং পঠনযোগ্য করে তোলে। async কীওয়ার্ড একটি ফাংশনকে অ্যাসিনক্রোনাস হিসেবে চিহ্নিত করে, এবং await ফলাফল প্রাপ্ত না হওয়া পর্যন্ত এর নির্বাহ স্থগিত করে।
মূল পয়েন্ট
Async/Await একটি ভাষা নির্মাণ যা আপনাকে সিনক্রোনাস কোডের মতোই রৈখিকভাবে অ্যাসিনক্রোনাস কোড লিখতে দেয়। Swift-এ, এটি iOS 13 / macOS 10.15-এ Swift Concurrency ফ্রেমওয়ার্কের সাথে এসেছে। Kotlin-এ, async/await সংস্করণ 1.3 থেকে করুটিন লাইব্রেরি (kotlinx.coroutines) এর মাধ্যমে উপলব্ধ।
async/await-এর আগে, অ্যাসিনক্রোনাস কোড কলব্যাক, GCD বা RxSwift-এর উপর ভিত্তি করে তৈরি হত। নেস্টেড কলব্যাকের চেইন কলব্যাক হেল-এর দিকে নিয়ে যেত — গভীর নেস্টিং যা পড়া এবং ডিবাগ করা কঠিন করে তোলে। Async/Await এই সমস্যার সমাধান করে, অ্যাসিনক্রোনাস ফাংশনগুলিকে await পয়েন্টে “স্থগিত” হতে এবং ফলাফল পাওয়ার পর পুনরায় শুরু হতে দেয়।
Google (2025) অনুসারে, Kotlin-এ async/await ব্যবহার করলে কলব্যাক পদ্ধতির তুলনায় অ্যাসিনক্রোনাস কোডের লাইন 40–60% হ্রাস পায়। Swift-এ, Swift Concurrency গ্রহণের হার 2025 সালে প্রকাশিত অ্যাপ্লিকেশনগুলির মধ্যে 68% এ পৌঁছেছে। iOS 16 UIKit, SwiftUI এবং Foundation-এ Swift Concurrency সমর্থন যুক্ত করেছে, যা async/await-কে সমস্ত নতুন Apple প্রকল্পের জন্য মানক সরঞ্জামে পরিণত করেছে।
async/await এবং থ্রেডের মধ্যে মূল পার্থক্য হল ব্লকিং ছাড়া স্থগিতকরণ। যখন একটি ফাংশন await-এর মুখোমুখি হয়, এটি স্থগিত হয়, বর্তমান থ্রেডকে অন্যান্য কাজের জন্য মুক্ত করে। অ্যাসিনক্রোনাস অপারেশন শেষ হওয়ার পর, ফাংশন একই বা ভিন্ন থ্রেডে পুনরায় শুরু হয়। একে সহযোগী মাল্টিটাস্কিং বলা হয়।
একটি async ফাংশন একটি স্টেট মেশিনে কম্পাইল হয় — একটি সসীম অটোমেটন যা নির্বাহের অবস্থা পরিচালনা করে। await বিন্দুতে, কম্পাইলার কনটেক্সট (স্থানীয় ভেরিয়েবল, রিটার্ন ঠিকানা) সংরক্ষণ করে এবং নিয়ন্ত্রণ রানটাইমের কাছে হস্তান্তর করে। ফলাফল প্রস্তুত হলে, রানটাইম কনটেক্সট পুনরুদ্ধার করে এবং নির্বাহ চালিয়ে যায়।
Swift-এ, এই স্টেট মেশিনটি SIL (Swift Intermediate Language) কম্পাইলার স্তরে বাস্তবায়িত। Kotlin-এ, Continuation Passing Style (CPS) পদ্ধতি ব্যবহার করা হয়: প্রতিটি সাসপেন্ড ফাংশন একটি লুকানো Continuation প্যারামিটার গ্রহণ করে যার মাধ্যমে ফলাফল ফেরত দেওয়া হয়। উভয় পদ্ধতিই মেমরি লিক ছাড়া নিরাপদ পুনরায় শুরু করার নিশ্চয়তা দেয়।
কলব্যাক পদ্ধতি একটি ক্লোজার পাস করার প্রয়োজন যা অপারেশন শেষ হওয়ার পরে কল করা হয়। তিনটি অনুক্রমিক অনুরোধের সাথে, আপনি প্রতিটি স্তরে ত্রুটি পরিচালনাসহ তিনটি স্তরের নেস্টিং পান। Async/Await সেই একই তিনটি অনুরোধকে একটি একক catch ব্লকসহ তিনটি অনুক্রমিক লাইনে পরিণত করে।
GCD (DispatchQueue) সিরিয়াল কিউ এবং DispatchGroup-এর মাধ্যমে কলব্যাক হেল সমাধান করে, তবে ভার্বোজ থাকে। একটি সাধারণ কাজের জন্য — ব্যবহারকারী লোড করুন, তারপর বন্ধু, তারপর UI — কিউ, গ্রুপ এবং নোটিফাই ব্লক তৈরির প্রয়োজন হয়। Async/Await একই ফাংশনে তিনটি লাইন দিয়ে একই কাজ করে।
| দিক | কলব্যাক | GCD | Async/Await |
|---|---|---|---|
| নেস্টিং | গভীর (ধ্বংসের পিরামিড) | মাঝারি (গ্রুপ+নোটিফাই) | রৈখিক (সমতল) |
| ত্রুটি পরিচালনা | প্রতি-কলব্যাক | ম্যানুয়াল | একীভূত (try/catch) |
| বাতিলকরণ | ম্যানুয়াল | সীমিত | Task.cancel() |
| থ্রেড নিরাপত্তা | ম্যানুয়াল | সিরিয়াল কিউর মাধ্যমে | MainActor-এর মাধ্যমে |
Apple WWDC 2024 অনুসারে, Swift Concurrency async/await নতুন কোডের জন্য প্রস্তাবিত পদ্ধতি। GCD C লাইব্রেরির সাথে একীকরণ এবং নির্দিষ্ট নিম্ন-স্তরের থ্রেড হ্যান্ডলিং পরিস্থিতির জন্য রয়ে গেছে।
Task Swift-এ অ্যাসিনক্রোনাস কাজের মৌলিক একক। একটি Task বিদ্যমান অ্যাক্টরের প্রসঙ্গে বা যেকোনো থ্রেডে তৈরি করা হয়। Task-এর ভিতরে, await-এর মাধ্যমে async ফাংশন কল করা যায়। TaskGroup একাধিক চাইল্ড টাস্ক সমান্তরালে শুরু করতে এবং তাদের ফলাফল সংগ্রহ করতে দেয় — এটি DispatchGroup-এর একটি উন্নত সংস্করণ।
Actor একটি থ্রেড-নিরাপদ রেফারেন্স টাইপ যা তার অবস্থাকে ডেটা রেস থেকে রক্ষা করে। কম্পাইলার নিশ্চিত করে যে অ্যাক্টর বৈশিষ্ট্যগুলিতে অ্যাক্সেস কেবল async কলের মাধ্যমে বা অ্যাক্টর আইসোলেশনের মধ্যে সম্ভব। Actor ম্যানুয়াল লক ছাড়া শেয়ার্ড মিউটেবল স্টেট রক্ষার জন্য সিরিয়াল DispatchQueue প্রতিস্থাপন করে।
Structured Concurrency-এর নীতি বলে: প্রত্যেক অ্যাসিনক্রোনাস টাস্কের একটি প্যারেন্ট থাকে, এবং প্যারেন্ট সম্পূর্ণ হয় না যতক্ষণ না তার সমস্ত শিশু সম্পূর্ণ হয়। যদি টাস্ক A Task { await B() } শুরু করে, তাহলে A B-এর জন্য অপেক্ষা করে। এটি টাস্ক লিক প্রতিরোধ করে এবং একটি পূর্বাভাসযোগ্য জীবনচক্র নিশ্চিত করে।
Kotlin-এ, async/await করুটিন-এর মাধ্যমে বাস্তবায়িত — ভাষার হালকা ওজনের থ্রেড। একটি ফাংশন suspend কীওয়ার্ড দিয়ে চিহ্নিত করা হয় (Swift-এর async-এর অনুরূপ)। চালু করার জন্য launch (ফায়ার-এন্ড-ফরগেট) বা async (ফলাফলসহ) ব্যবহার করা হয়। Async থেকে ফলাফল পেতে Await কল করা হয়।
Dispatcher নির্ধারণ করে কোন থ্রেড পুলে করুটিন চলবে: UI-র জন্য Dispatchers.Main, নেটওয়ার্ক/ডিস্কের জন্য Dispatchers.IO এবং CPU-নিবিড় কাজের জন্য Dispatchers.Default। Structured Concurrency CoroutineScope-এর মাধ্যমে নিশ্চিত করা হয় — সুযোগ বাতিল হলে, সমস্ত চাইল্ড করুটিন বাতিল হয়ে যায়।
JetBrains (2025) অনুসারে, Google Play-এ 97% Android অ্যাপ kotlinx.coroutines ব্যবহার করে, এবং তাদের মধ্যে 82% নেটওয়ার্ক অনুরোধের জন্য async/await প্রয়োগ করে। করুটিন Android-এ অ্যাসিনক্রোনাস প্রোগ্রামিংয়ের জন্য ডি-ফ্যাক্টো মানদণ্ডে পরিণত হয়েছে। Kotlin Multiplatform-ও করুটিন সমর্থন করে, যা Android, iOS এবং সার্ভার সাইডে শেয়ার্ড অ্যাসিনক্রোনাস কোড ব্যবহারের অনুমতি দেয়।
আসুন প্রতিটি ভাষার জন্য দুটি উদাহরণ দেখি: অনুক্রমিক ডেটা লোডিং এবং TaskGroup বা async/await সহ সমান্তরাল অনুরোধ।
await ব্যবহারকারীর ডেটা পাওয়া পর্যন্ত, তারপর বন্ধু পাওয়া পর্যন্ত নির্বাহ স্থগিত করে। কোনও নেস্টেড ক্লোজার নেই।
func loadProfile() async throws -> Profile {
let user = try await api.fetchUser()
let friends = try await api.fetchFriends(for: user.id)
return Profile(user: user, friends: friends)
}
TaskGroup কাজগুলি সমান্তরালে শুরু করে এবং ফলাফলগুলি একটি অ্যারেতে সংগ্রহ করে। ফলাফলের ক্রম শুরুর ক্রমের সাথে মিল নাও হতে পারে।
func loadParallel() async throws -> [String] {
await withThrowingTaskGroup(of: String.self) { group in
group.addTask { try await api.fetchName() }
group.addTask { try await api.fetchEmail() }
group.addTask { try await api.fetchAvatar() }
var results = [String]()
for try await value in group { results.append(value) }
return results
}
}
suspend ফাংশনগুলি অন্য suspend ফাংশন কল করতে পারে। Swift-এর অনুরূপ: অনুক্রমিক কল।
suspend fun loadProfile(): Profile {
val user = api.fetchUser()
val friends = api.fetchFriends(user.id)
return Profile(user, friends)
}
Kotlin-এ, সমান্তরালতা প্রতিটি অনুরোধের জন্য async সহ coroutineScope-এর মাধ্যমে অর্জিত হয়।
suspend fun loadParallel(): List<String> = coroutineScope {
val name = async { api.fetchName() }
val email = async { api.fetchEmail() }
val avatar = async { api.fetchAvatar() }
listOf(name.await(), email.await(), avatar.await())
}
ভুলে যাওয়া Task { } — একটি async ফাংশনকে Task-এ মোড়ানো ছাড়া সিনক্রোনাস কনটেক্সট থেকে কল করা যায় না। Swift-এ, এটি ত্রুটিসহ কম্পাইল হয়। Kotlin-এ, lifecycleScope বা viewModelScope-এর মাধ্যমে চালু করার প্রয়োজন। সাধারণ ফাংশন থেকে suspend ফাংশন কল করার চেষ্টা কম্পাইল হবে না।
প্রত্যেক ফাংশনকে অ্যাসিনক্রোনাস করার প্রয়োজন নেই। I/O ছাড়া CPU-নিবিড় কাজগুলি async থেকে লাভবান হয় না — সেগুলিকে .userInitiated QoS সহ DispatchQueue-তে নির্বাহ করা ভাল। Async/Await I/O-বাউন্ড অপারেশনের জন্য অপ্টিমাইজড: নেটওয়ার্ক, ডিস্ক, অপেক্ষা।
মূল থ্রেডে .result ব্যবহার (একটি async ফাংশনের ফলাফলের জন্য সিনক্রোনাস অপেক্ষা) ব্লকিংয়ের দিকে নিয়ে যায়। Swift-এ, Task.synchronousWait Apple-এর দ্বারা সুপারিশকৃত নয়। Kotlin-এ, মূল থ্রেডে runBlocking একটি অ্যান্টিপ্যাটার্ন — lifecycleScope ব্যবহার করুন।
যদি Task একটি ক্লাস প্রপার্টিতে সংরক্ষিত না হয়, কনটেক্সট ছেড়ে যাওয়ার পর এটি বাতিল হয়ে যায়। Swift-এ, Task স্কোপড — এর জীবনচক্র তৈরি করার কনটেক্সটের সাথে আবদ্ধ। দীর্ঘস্থায়ী অপারেশনের প্রয়োজন হলে Task একটি প্রপার্টিতে সংরক্ষণ করুন।
প্রায়শই জিজ্ঞাসিত প্রশ্ন
Async/Await একটি ভাষা নির্মাণ যাতে কিউ তৈরি করার প্রয়োজন নেই। DispatchQueue থ্রেড পরিচালনার জন্য একটি সিস্টেম API। Async/await ভাষা স্তরে একটি স্টেট মেশিনে কম্পাইল হয়, GCD — OS স্তরে syscalls-এ।
না — await ফাংশন স্থগিত করে কিন্তু থ্রেডকে অন্যান্য কাজের জন্য মুক্ত করে। অপারেশন শেষ হলে, ফাংশন পুলের যেকোনো উপলব্ধ থ্রেডে পুনরায় শুরু হয়।
হ্যাঁ — Swift-এ Task.cancel() বা Kotlin-এ Job.cancel()-এর মাধ্যমে। বাতিলকরণ Structured Concurrency অনুসারে সমস্ত চাইল্ড টাস্কে ছড়িয়ে পড়ে। কোড Task.isCancelled বা ensureActive()-এর মাধ্যমে বাতিলকরণ ফ্ল্যাগ পরীক্ষা করে।
MainActor একটি অ্যাক্টর যার বৈশিষ্ট্য এবং পদ্ধতিগুলি সর্বদা মূল থ্রেডে নির্বাহিত হয়। একটি ফাংশনকে @MainActor দিয়ে চিহ্নিত করে, আপনি নিশ্চিত করেন যে UI আপডেটগুলি সঠিক থ্রেডে ঘটে, DispatchQueue.main.async প্রতিস্থাপন করে।
Async/Await Swift (iOS 13+), Kotlin (kotlinx.coroutines-এর মাধ্যমে), Dart (Flutter), JavaScript/TypeScript, Python, C#, Rust এবং Go-তে (সিনট্যাকটিক সুগারসহ goroutines-এর মাধ্যমে) উপলব্ধ।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন