Az Async/Await — egy kulcsszópár aszinkron kód írásához szinkron stílusban, elérhető Swiftben iOS 13-tól és Kotlinban korutinokkal. Az Apple Swift Documentation, 2026 szerint a Async/Await helyettesíti a callback láncokat és a GCD-t, lineárissá és olvashatóvá téve az aszinkron kódot. Az async kulcsszó aszinkronnak jelöl egy függvényt, az await pedig felfüggeszti annak végrehajtását az eredmény megérkezéséig.
Főbb pontok
Async/Await — egy nyelvi konstrukció, amely lehetővé teszi aszinkron kód írását ugyanolyan lineárisan, mint a szinkron kódot. Swiftben az iOS 13 / macOS 10.15-ben jelent meg a Swift Concurrency keretrendszerrel együtt. Kotlinban az async/await a korutin könyvtáron (kotlinx.coroutines) keresztül érhető el az 1.3-as verziótól.
Az async/await megjelenése előtt az aszinkron kód callback-ekre, GCD-re vagy RxSwift-re épült. A beágyazott callback-ek láncai callback hellhez vezettek — mély beágyazáshoz, ami megnehezíti az olvasást és a hibakeresést. Az Async/Await megoldja ezt a problémát azzal, hogy az aszinkron függvények „felfüggeszthetők” az await pontokon és folytathatók az eredmény megérkezése után.
A Google adatai szerint (2025), az async/await használata Kotlinban 40–60%-kal csökkenti az aszinkron kód sorainak számát a callback megközelítéshez képest. Swiftben a Swift Concurrency elfogadottsága 68%-ot ért el a közzétett alkalmazások körében 2025-ben. iOS 16 hozzáadta a Swift Concurrency támogatását UIKitben, SwiftUI-ban és Foundationben, ezzel az async/await szabványos eszközzé vált az összes új Apple projekt számára.
Az async/await fő különbsége a szálakhoz képest — felfüggesztés blokkolás nélkül. Amikor egy függvény await-be ütközik, felfüggesztődik, felszabadítva az aktuális szálat más feladatok számára. Az aszinkron művelet befejezése után a függvény ugyanazon vagy másik szálon folytatódik. Ezt hívják cooperative multitaskingnak.
Az async függvény state machine-né — egy véges állapotgéppé — fordul, amely a végrehajtási állapotokat kezeli. Az await pontnál a fordító elmenti a kontextust (lokális változók, visszatérési cím) és átadja a vezérlést a runtime-nak. Amikor az eredmény kész, a runtime visszaállítja a kontextust és folytatja a végrehajtást.
Swiftben ez a state machine a SIL (Swift Intermediate Language) fordító szintjén van megvalósítva. Kotlinban — a Continuation Passing Style (CPS) mechanizmusán keresztül: minden suspend függvény egy rejtett Continuation paramétert kap, amelyen keresztül az eredmény visszaadódik. Mindkét megközelítés garantálja a biztonságos folytatást memóriaszivárgás nélkül.
Callback megközelítés egy closure átadását igényli, amely a művelet befejezése után hívódik meg. Három egymást követő kérésnél három szintű beágyazás keletkezik hibakezeléssel minden szinten. Async/Await ugyanezt a három kérést három egymást követő sorrá alakítja egyetlen catch blokkal.
GCD (DispatchQueue) megoldja a callback hell problémáját soros sorok és DispatchGroup segítségével, de bőbeszédű marad. Egy egyszerű feladathoz — user betöltése, majd friends, majd UI — sorok, csoportok és notify blokkok létrehozása szükséges. Async/Await ugyanezt a feladatot három sorral végzi el egy függvényben.
| Szempont | Callback | GCD | Async/Await |
|---|---|---|---|
| Beágyazás | Mély (pyramid of doom) | Közepes (csoportok+notify) | Lineáris (flat) |
| Hibakezelés | Per-callback | Kézi | Egységes (try/catch) |
| Megszakítás | Kézi | Korlátozott | Task.cancel() |
| Thread safety | Kézi | Soros soron keresztül | MainActor-on keresztül |
Az Apple WWDC 2024 adatai szerint, a Swift Concurrency async/await az ajánlott megközelítés új kódhoz. A GCD továbbra is C-könyvtárakkal való integrációra és specifikus alacsony szintű szálkezelési forgatókönyvekre marad.
Task — az aszinkron munka alapvető egysége Swiftben. A Task egy létező actor kontextusában vagy bármely szálon jön létre. A Task-on belül async függvények hívhatók await segítségével. TaskGroup több gyermek feladat párhuzamos futtatását és azok eredményeinek összegyűjtését teszi lehetővé — a DispatchGroup szteroidokon változata.
Actor — egy szálbiztos referencia típus, amely megvédi állapotát az adatversenytől. A fordító garantálja, hogy az actor tulajdonságaihoz csak async hívásokon vagy actor izoláción belül lehet hozzáférni. Actor helyettesíti a soros DispatchQueue-t a megosztott változó állapot védelmében kézi zárak nélkül.
A Structured Concurrency elve kimondja: minden aszinkron feladatnak van szülője, és a szülő nem fejeződik be, amíg az összes gyermeke be nem fejeződött. Ha az A feladat elindítja a Task { await B() }-t, akkor A vár B-re. Ez megakadályozza a feladatok szivárgását és kiszámítható életciklust biztosít.
Kotlinban az async/await coroutines — a nyelv könnyű szálain keresztül van megvalósítva. A függvény a suspend kulcsszóval van jelölve (a Swift async megfelelője). Indításhoz a launch (fire-and-forget) vagy async (eredménnyel) használható. Az Await az async eredményének lekérésére szolgál.
Dispatcher határozza meg, hogy a korutin melyik szálpoolban fut: Dispatchers.Main UI-hoz, Dispatchers.IO hálózathoz/lemezhez és Dispatchers.Default CPU-intenzív feladatokhoz. Structured Concurrency a CoroutineScope-on keresztül biztosított — a scope megszakításakor az összes gyermek korutin megszakad.
A JetBrains adatai szerint (2025), az Android alkalmazások 97%-a a Google Play-en használ kotlinx.coroutines-t, és 82%-uk alkalmaz async/await-t hálózati kérésekhez. A coroutines de facto szabvánnyá vált az aszinkron programozásban Androidon. Kotlin Multiplatform szintén támogatja a korutinokat, lehetővé téve közös aszinkron kód használatát Androidon, iOS-en és szerveroldalon.
Nézzünk két példát mindkét nyelvhez: szekvenciális adatbetöltés és párhuzamos kérések TaskGroup vagy async/await segítségével.
await felfüggeszti a végrehajtást a felhasználó adatainak lekéréséig, majd — a barátok lekéréséig. Nincsenek beágyazott zárójelek.
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 párhuzamosan futtatja a feladatokat és összegyűjti az eredményeket egy tömbbe. Az eredmények sorrendje nem feltétlenül egyezik meg az indítás sorrendjével.
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
}
}
A suspend függvények képesek más suspend függvényeket hívni. Swift megfelelője: szekvenciális hívások.
suspend fun loadProfile(): Profile {
val user = api.fetchUser()
val friends = api.fetchFriends(user.id)
return Profile(user, friends)
}
Kotlinban a párhuzamosság coroutineScope-on keresztül érhető el async segítségével minden kéréshez.
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())
}
Elfelejtett Task { } – aszinkron függvény nem hívható szinkron kontextusból Task-ba csomagolás nélkül. Swiftben ez fordítási hibát okoz. Kotlinban lifecycleScope vagy viewModelScope használata szükséges. Ha egy suspend függvényt egy szokványos függvényből próbálnak meghívni, az nem fordul le.
Nem kell minden függvényt aszinkronná tenni. CPU-intenzív feladatok I/O nélkül nem profitálnak az async-ból — jobb ezeket DispatchQueue-on futtatni .userInitiated QoS-sel. Az Async/Await I/O-bound műveletekre van optimalizálva: hálózat, lemez, várakozás.
A .result használata a főszálon (async függvény eredményének szinkron várakozása) blokkoláshoz vezet. Swiftben a Task.synchronousWait nem ajánlott az Apple által. Kotlinban a runBlocking a főszálon antipattern, használjon lifecycleScope-t.
Ha a Task nincs elmentve egy osztály tulajdonságába, a kontextus elhagyása után megszakad. Swiftben a Task scoped — életciklusa a létrehozó kontextushoz van kötve. Mentse el a Task-ot tulajdonságba, ha hosszan futó műveletre van szükség.
Gyakran ismételt kérdések
Async/Await — nyelvi konstrukció, amely nem igényel sorok létrehozását. DispatchQueue — egy rendszer API a szálak kezelésére. Az async/await nyelvi szinten fordul state machine-né, a GCD — syscallá az OS szintjén.
Nem — az await felfüggeszti a függvényt, de felszabadítja a szálat más feladatok számára. A művelet befejezése után a függvény bármely elérhető szálon folytatódik a poolból.
Igen — Task.cancel() segítségével Swiftben vagy Job.cancel() segítségével Kotlinban. A megszakítás az összes gyermek feladatra terjed a Structured Concurrency szerint. A kód maga ellenőrzi a megszakítási jelzőt a Task.isCancelled vagy ensureActive() segítségével.
MainActor — egy actor, amelynek tulajdonságai és metódusai mindig a főszálon hajtódnak végre. Egy függvény @MainActor-ral való megjelölésével garantálja, hogy a UI-frissítések a megfelelő szálon történnek, helyettesítve a DispatchQueue.main.async hívást.
Az Async/Await elérhető a következő nyelvekben: Swift (iOS 13+), Kotlin (kotlinx.coroutines-on keresztül), Dart (Flutter), JavaScript/TypeScript, Python, C#, Rust és Go (goroutines-on keresztül szintaktikai cukorral).
Összefoglaló
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is