Middle
¿Qué capacidades ofrece Kotlin para trabajar con operaciones asíncronas?
sobes.tech AI
Respuesta de la IA
Kotlin proporciona corrutinas para simplificar operaciones asíncronas, ofreciendo hilos ligeros que no bloquean el hilo principal.
Funciones clave:
- Funciones de Suspensión: Funciones con la palabra clave
suspend, que pueden ser suspendidas y reanudadas. No bloquean el hilo en el que se ejecutan.suspend fun fetchData(): String { delay(1000) // Simula una operación larga return "Datos recibidos" } - Constructores de Corrutinas: Funciones utilizadas para lanzar corrutinas:
launch: Inicia una nueva corrutina y devuelve unJob(no bloqueante).GlobalScope.launch { println("Corrutina lanzada") }async: Inicia una nueva corrutina y devuelve unDeferred<T>(bloqueante al llamar a.await()).val deferred = GlobalScope.async { fetchData() } // ... val result = deferred.await() // Espera el resultadorunBlocking: Bloquea el hilo actual hasta que la corrutina termine (usado en puentes entre código bloqueante y no bloqueante, por ejemplo, en pruebas).runBlocking { val data = fetchData() println(data) }
- Contexto de Corrutina: Conjunto de elementos que definen el comportamiento de la corrutina, incluyendo
DispatcheryJob.Dispatcher: Define el hilo o grupo de hilos donde se ejecuta la corrutina.
- Dispatchers: Objetos integrados para gestionar hilos:
Dispatchers.Default: Grupo de hilos de fondo compartido.Dispatchers.IO: Optimizado para entrada/salida (operaciones de disco, red).Dispatchers.Main: Hilo principal de UI (para Android, JavaFX, etc.).Dispatchers.Unconfined: Ejecuta la corrutina en el hilo actual, pero puede reanudarse en cualquier hilo después de una suspensión.
GlobalScope.launch(Dispatchers.IO) { // Se ejecuta en un hilo de entrada/salida } - Concurrencia Estructurada: Principio según el cual las corrutinas tienen un padre (
CoroutineScope) y se cancelan automáticamente al cancelar el padre. Previene fugas de recursos y simplifica la gestión del ciclo de vida.// CoroutineScope gestiona automáticamente las corrutinas hijas val scope = CoroutineScope(Dispatchers.Default) val job = scope.launch { // ... } // Al cancelar el scope, se cancelan todas las corrutinas hijas scope.cancel() - Canales: Para transferencia segura de datos entre corrutinas. Pueden ser:
- Sin búfer: La recepción solo ocurre después del envío.
- Búfer: Permite enviar varios elementos antes de bloquear.
- Conflated: Solo almacena el último elemento enviado.
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: Flujo de datos que puede emitir varios valores de forma asíncrona. Similar a RxJava
Observable, pero más ligero e integrado con corrutinas.fun simpleFlow(): Flow<Int> = flow { for (i in 1..3) { delay(100) emit(i) // Envío de valor } } runBlocking { simpleFlow().collect { value -> println(value) } // Consumo de valores }
Estas capacidades permiten escribir código asíncrono en estilo imperativo, haciéndolo más legible y fácil de mantener en comparación con el uso de callbacks o Future.