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) میکانزم استعمال ہوتا ہے: ہر suspend فنکشن ایک پوشیدہ Continuation پیرامیٹر قبول کرتا ہے جس کے ذریعے نتیجہ واپس کیا جاتا ہے۔ دونوں طریقے میموری لیک کے بغیر محفوظ دوبارہ شروع ہونے کی ضمانت دیتے ہیں۔
کال بیک طریقہ میں ایک کلوزر پاس کرنے کی ضرورت ہوتی ہے جو کارروائی مکمل ہونے کے بعد بلایا جاتا ہے۔ تین ترتیب وار درخواستوں کے ساتھ، آپ کو ہر سطح پر غلطی کے انتظام کے ساتھ تین سطحوں کی نیسٹنگ ملتی ہے۔ Async/Await انہی تین درخواستوں کو ایک ہی catch بلاک کے ساتھ تین ترتیب وار سطور میں بدل دیتا ہے۔
GCD (DispatchQueue) سیریل قطاروں اور DispatchGroup کے ذریعے کال بیک جہنم کو حل کرتا ہے، لیکن پھر بھی طویل ہے۔ ایک سادہ کام کے لیے — صارف لوڈ کریں، پھر دوست، پھر UI — قطاریں، گروپس اور notify بلاکس بنانے کی ضرورت ہوتی ہے۔ 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 (نتیجہ کے ساتھ) استعمال ہوتا ہے۔ Await کو async سے نتیجہ حاصل کرنے کے لیے بلایا جاتا ہے۔
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 سطح پر سسٹم کالز میں۔
نہیں — 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 ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں