Async/Await — to je dvojice klíčových slov pro psaní asynchronního kódu v synchronním stylu, dostupná ve Swift od iOS 13 a v Kotlin s korutinami. Podle Apple Swift Documentation, 2026, Async/Await nahrazuje řetězce callbacků a GCD, čímž činí asynchronní kód lineárním a čitelným. Klíčové slovo async označuje funkci jako asynchronní a await pozastavuje její provádění až do získání výsledku.
Hlavní body
Async/Await — to je jazyková konstrukce, která umožňuje psát asynchronní kód stejně lineárně jako synchronní. Ve Swift se objevila v iOS 13 / macOS 10.15 společně s frameworkem Swift Concurrency. V Kotlin je async/await dostupný přes knihovnu korutin (kotlinx.coroutines) od verze 1.3.
Před příchodem async/await se asynchronní kód stavěl na callback, GCD nebo RxSwift. Řetězce vnořených callbacků vedly k callback hell — hlubokému vnoření, které komplikuje čtení a ladění. Async/Await tento problém řeší tím, že asynchronní funkce se mohou „pozastavit“ v bodech await a obnovit se po získání výsledku.
Podle údajů Google (2025), použití async/await v Kotlin snižuje počet řádků asynchronního kódu o 40–60 % ve srovnání s přístupem callbacků. Ve Swift dosáhlo přijetí Swift Concurrency 68 % mezi publikovanými aplikacemi v roce 2025. iOS 16 přidala podporu Swift Concurrency v UIKit, SwiftUI a Foundation, což učinilo async/await standardním nástrojem pro všechny nové projekty Apple.
Klíčový rozdíl async/await od vláken — pozastavení bez blokování. Když funkce narazí na await, pozastaví se a uvolní aktuální vlákno pro jiné úkoly. Po dokončení asynchronní operace se funkce obnoví na stejném nebo jiném vlákně. Tomu se říká cooperative multitasking.
Async funkce je kompilována do state machine — konečného automatu, který řídí stavy provádění. V bodě await kompilátor uloží kontext (lokální proměnné, adresu návratu) a předá řízení runtime. Když je výsledek připraven, runtime obnoví kontext a pokračuje v provádění.
Ve Swift je tato state machine implementována na úrovni kompilátoru SIL (Swift Intermediate Language). V Kotlin — pomocí mechanismu Continuation Passing Style (CPS): každá suspend funkce přijímá skrytý parametr Continuation, prostřednictvím kterého se vrací výsledek. Oba přístupy zaručují bezpečné obnovení bez úniků paměti.
Callback přístup vyžaduje předání uzavření, které je voláno po dokončení operace. Při třech po sobě jdoucích požadavcích vznikají tři úrovně vnoření s ošetřením chyb na každé. Async/Await mění stejné tři požadavky na tři po sobě jdoucí řádky s jediným blokem catch.
GCD (DispatchQueue) řeší problém callback hell pomocí sériových front a DispatchGroup, ale zůstává mnohomluvný. Pro jednoduchý úkol — načíst user, poté friends, poté UI — je třeba vytvoření front, skupin a notify bloků. Async/Await provádí stejný úkol třemi řádky v jedné funkci.
| Aspekt | Callback | GCD | Async/Await |
|---|---|---|---|
| Vnoření | Hluboké (pyramid of doom) | Střední (skupiny+notify) | Lineární (flat) |
| Ošetření chyb | Per-callback | Ruční | Jednotné (try/catch) |
| Zrušení | Ruční | Omezené | Task.cancel() |
| Thread safety | Ruční | Přes sériovou frontu | Přes MainActor |
Podle údajů Apple WWDC 2024, Swift Concurrency async/await — doporučený přístup pro nový kód. GCD zůstává pro integraci s C-knihovnami a specifické low-level scénáře zpracování vláken.
Task — to je základní jednotka asynchronní práce ve Swift. Task se vytváří v kontextu existujícího aktoru nebo na libovolném vlákně. Uvnitř Task lze volat async funkce přes await. TaskGroup umožňuje spouštět několik podřízených úkolů paralelně a sbírat jejich výsledky — obdoba DispatchGroup na steroidech.
Actor — vláknově bezpečný reference type, který chraní svůj stav před datovými závody. Kompilátor zaručuje, že přístup k vlastnostem actor je možný pouze přes async volání nebo v rámci actor isolation. Actor nahrazuje sériovou DispatchQueue pro ochranu shared mutable state bez ručních zámků.
Princip Structured Concurrency říká: každý asynchronní úkol má rodiče a rodič se nedokončí, dokud nejsou dokončeny všechny jeho děti. Pokud úkol A spustí Task { await B() }, pak A čeká na B. To zabraňuje úniku úkolů a zajišťuje předvídatelný lifecycle.
V Kotlin je async/await implementován pomocí coroutines — lehkých vláken jazyka. Funkce je označena klíčovým slovem suspend (obdoba Swift’s async). Pro spuštění se používá launch (fire-and-forget) nebo async (s výsledkem). Await se volá pro získání výsledku z async.
Dispatcher určuje, na jakém fondu vláken se korutina provádí: Dispatchers.Main pro UI, Dispatchers.IO pro síť/disk a Dispatchers.Default pro CPU-intenzivní úkoly. Structured Concurrency je zajištěna pomocí CoroutineScope — při zrušení scope jsou zrušeny všechny podřízené korutiny.
Podle údajů JetBrains (2025), 97 % Android aplikací v Google Play používá kotlinx.coroutines a 82 % z nich používá async/await pro síťové požadavky. Coroutines se staly de facto standardem pro asynchronní programování v Android. Kotlin Multiplatform také podporuje korutiny, což umožňuje používat společný asynchronní kód na Android, iOS a serverové části.
Podívejme se na dva příklady pro každý jazyk: sekvenční načítání dat a paralelní požadavky s TaskGroup nebo async/await.
await pozastavuje provádění do získání dat uživatele, poté — do získání přátel. Žádná vnořená uzavření.
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 spouští úkoly paralelně a sbírá výsledky do pole. Pořadí výsledků se nemusí shodovat s pořadím spuštění.
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 funkce mohou volat jiné suspend funkce. Obdoba Swift: sekvenční volání.
suspend fun loadProfile(): Profile {
val user = api.fetchUser()
val friends = api.fetchFriends(user.id)
return Profile(user, friends)
}
V Kotlin je paralelismu dosaženo pomocí coroutineScope s async pro každý požadavek.
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())
}
Zapomenutý Task { } — asynchronní funkci nelze zavolat ze synchronního kontextu bez obalení do Task. Ve Swift to způsobí chybu při kompilaci. V Kotlin je vyžadováno spuštění přes lifecycleScope nebo viewModelScope. Pokus o zavolání suspend funkce z běžné funkce se nezkompiluje.
Ne každou funkci je třeba dělat asynchronní. CPU-intenzivní úkoly bez I/O nezískávají z async — je lepší je provádět na DispatchQueue s .userInitiated QoS. Async/Await je optimalizován pro I/O-bound operace: síť, disk, čekání.
Použití .result na hlavním vlákně (synchronní čekání na výsledek async funkce) vede k blokování. Ve Swift Task.synchronousWait není doporučeno Apple. V Kotlin runBlocking na hlavním vlákně je antipattern, používejte lifecycleScope.
Pokud Task není uložen do vlastnosti třídy, po opuštění kontextu je zrušen. Ve Swift je Task scoped — jeho životní cyklus je vázán na vytvářející kontext. Ukládejte Task do vlastnosti při potřebě dlouhotrvající operace.
Často kladené otázky
Async/Await — jazyková konstrukce, která nevyžaduje vytváření front. DispatchQueue — to je systémové API pro správu vláken. Async/await je kompilován do state machine na úrovni jazyka, GCD — do syscall na úrovni OS.
Ne — await pozastavuje funkci, ale uvolňuje vlákno pro jiné úkoly. Po dokončení operace se funkce obnoví na libovolném dostupném vlákně z fondu.
Ano — pomocí Task.cancel() ve Swift nebo Job.cancel() v Kotlin. Zrušení se šíří na všechny podřízené úkoly podle Structured Concurrency. Kód sám kontroluje příznak zrušení pomocí Task.isCancelled nebo ensureActive().
MainActor — to je actor, jehož vlastnosti a metody se vždy provádějí na hlavním vlákně. Označením funkce @MainActor zaručujete, že UI aktualizace probíhají na správném vlákně, čímž nahrazujete DispatchQueue.main.async.
Async/Await je dostupný v Swift (iOS 13+), Kotlin (přes kotlinx.coroutines), Dart (Flutter), JavaScript/TypeScript, Python, C#, Rust a Go (přes goroutines se syntaktickým cukrem).
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také