Middle
Jaké možnosti nabízí Kotlin pro práci s asynchronními operacemi?
sobes.tech AI
Odpověď od AI
Kotlin poskytuje korutiny (coroutines) pro zjednodušení asynchronních operací a nabízí lehké proudy, které nezablokují hlavní vlákno provádění.
Hlavní možnosti:
- Funkce pozastavení: Funkce označené klíčovým slovem
suspend, které lze pozastavit a pokračovat. Neblokují vlákno, ve kterém jsou prováděny.suspend fun fetchData(): String { delay(1000) // Napodobujeme dlouhou operaci return "Data získána" } - Stavitelé korutin: Funkce používané k spuštění korutin:
launch: Spustí novou korutinu a vrátíJob(neblokující).GlobalScope.launch { println("Korutina spuštěna") }async: Spustí novou korutinu a vrátíDeferred<T>(blokující při volání.await()).val deferred = GlobalScope.async { fetchData() } // ... val result = deferred.await() // Čeká na výsledekrunBlocking: Blokuje aktuální vlákno do dokončení korutiny (používá se hlavně jako most mezi blokujícím a neblokujícím kódem, například v testech).runBlocking { val data = fetchData() println(data) }
- CoroutineContext: Sada prvků určujících chování korutiny, včetně
DispatcheraJob.Dispatcher: Určuje vlákno nebo skupinu vláken, kde se korutina provádí.
- Dispatchers: Vestavěné objekty pro správu vláken:
Dispatchers.Default: Obecná skupina vláken na pozadí.Dispatchers.IO: Optimalizováno pro vstup/výstup (diskové, síťové operace).Dispatchers.Main: Hlavní vlákno UI (pro Android, JavaFX atd.).Dispatchers.Unconfined: Spouští korutinu v aktuálním vlákně, ale po pozastavení může pokračovat v libovolném vlákně.
GlobalScope.launch(Dispatchers.IO) { // Provádí se v vlákně vstupu/výstupu } - Strukturovaná konkurence: Princip, podle kterého mají korutiny rodiče (
CoroutineScope) a jsou automaticky zrušeny při zrušení rodiče. Zabraňuje únikům zdrojů a usnadňuje správu životního cyklu.// CoroutineScope automaticky spravuje podřízené korutiny val scope = CoroutineScope(Dispatchers.Default) val job = scope.launch { // ... } // Při zrušení scope jsou zrušeny všechny podřízené korutiny scope.cancel() - Kanály: Kanály pro bezpečný přenos dat mezi korutinami. Mohou být:
- Unbuffered: Přijímání se provádí až po odeslání.
- Buffered: Umožňuje odeslat několik prvků před blokováním.
- Conflated: Ukládá pouze poslední odeslaný prvek.
val channel = Channel<Int>() scope.launch { for (x in 1..5) channel.send(x) channel.close() } scope.launch { for (y in channel) println(y) } - Flow: Proud dat, který může emitovat několik hodnot asynchronně. Podobá se RxJava
Observable, ale je lehčí a integrovaný s korutinami.fun simpleFlow(): Flow<Int> = flow { for (i in 1..3) { delay(100) emit(i) // Odeslání hodnoty } } runBlocking { simpleFlow().collect { value -> println(value) } // Příjem hodnot }
Tyto možnosti umožňují psaní asynchronního kódu v imperativním stylu, což je čitelnější a lépe udržovatelné ve srovnání s použitím callbacků nebo Future.