Async/Await: lényeg, async függvények és munka az await-tel

Szerző: IT Sectr Megjelenés: 2026-03-16 Olvasási idő: 8 perc

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 — szintaktikai cukor aszinkron kódhoz beágyazott callbackek nélkül
  • async aszinkronnak és felfüggeszthetőnek jelöl egy függvényt
  • await felfüggeszti a függvény végrehajtását az aszinkron művelet befejeződéséig
  • Task Swiftben új aszinkron munkaegységet hoz létre kontextussal
  • Structured Concurrency garantiálja, hogy az összes gyermek feladat befejeződjön a szülő előtt

Mi az Async/Await és az aszinkron programozás

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.

Működési elv: felfüggeszthető függvények

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.

Hogyan működik az Async/Await: felfüggesztés és folytatás

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.

  • Swift — a fordító az async függvényt SIL-be alakítja runAsync coroutine frame-mel
  • Kotlin — minden suspend függvény megkapja a Continuation-t és delegálja a végrehajtást a dispatcher-nek
  • Mindkét nyelv — felszabadítja a szálat await-nél, anélkül hogy blokkolná azt a várakozás idejére
  • Kivételek — szabványos mechanizmusokon keresztül terjednek (throws / try-catch)

Async/Await vs Callbacks és GCD: megközelítések összehasonlítása

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.

SzempontCallbackGCDAsync/Await
BeágyazásMély (pyramid of doom)Közepes (csoportok+notify)Lineáris (flat)
HibakezelésPer-callbackKéziEgységes (try/catch)
MegszakításKéziKorlátozottTask.cancel()
Thread safetyKéziSoros soron keresztülMainActor-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.

Swift Concurrency: Task, TaskGroup és Actor

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.

Structured Concurrency

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.

Async/Await Kotlinban korutinokkal

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.

Kódpéldák Async/Await-tel Swiftben és Kotlinban

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.

Swift: szekvenciális async hívások

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.

swift
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)
}

Swift: párhuzamos kérések TaskGroup-pal

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.

swift
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
    }
}

Kotlin: szekvenciális hívás async/await-tel

A suspend függvények képesek más suspend függvényeket hívni. Swift megfelelője: szekvenciális hívások.

kotlin
suspend fun loadProfile(): Profile {
    val user = api.fetchUser()
    val friends = api.fetchFriends(user.id)
    return Profile(user, friends)
}

Kotlin: párhuzamos kérések async/await-tel

Kotlinban a párhuzamosság coroutineScope-on keresztül érhető el async segítségével minden kéréshez.

kotlin
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())
}

Tipikus hibák és korlátozások az Async/Await-ben

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.

Az async túlzott használata szükségtelenül

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 főszál blokkolása .result-en keresztül

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.

Task szivárgás megszakításkor

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

Miben különbözik az async/await a DispatchQueue-tól?

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.

Blokkolja-e az await a szálat?

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.

Megszakítható-e egy async feladat?

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.

Mi az a MainActor Swiftben?

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.

Mely nyelvekben érhető el az async/await?

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ó

  • Async/Await — nyelvi konstrukció lineáris aszinkron kódhoz callback hell nélkül
  • Swift Concurrency Task, TaskGroup, Actor és Structured Concurrency szolgáltatásokat nyújt
  • Kotlin coroutines suspend függvényeket, Dispatcher-eket és korutin scope-okat használ
  • Felfüggesztés blokkolás nélkül — fő különbség az async/away és a szálak/sorok között
  • Structured Concurrency garantálja az összes gyermek feladat befejeződését a szülő előtt
  • Async/Await vs GCD — az első előnyösebb új kódhoz, a második legacy és alacsony szintű feladatokhoz
  • MainActor Swiftben és Dispatchers.Main Kotlinban védi a UI szálat a háttérműveletektől

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.

Projekt megbeszélése

Olvassa el is