Programación asíncrona en Kotlin: guía completa

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Programación asíncrona en Kotlin: guía completa

La programación asíncrona es un enfoque de desarrollo en el que el programa no bloquea la ejecución esperando la finalización de operaciones largas (por ejemplo, solicitudes de red, lectura de archivos o trabajo con bases de datos). En su lugar, continúa ejecutando otras tareas y el resultado se devuelve más tarde. En el mundo de Kotlin, la herramienta principal para el trabajo asíncrono son las corrutinas (coroutines): hilos ligeros que permiten escribir código asíncrono casi como si fuera síncrono.

En este artículo, analizaremos cómo funciona la programación asíncrona en Kotlin, desde lo básico hasta técnicas avanzadas. Aprenderá a usar corrutinas de manera efectiva, evitar bloqueos y escribir aplicaciones escalables.



1. Fundamentos de las corrutinas en Kotlin

Las corrutinas son un concepto clave de la programación asíncrona en Kotlin. Permiten pausar la ejecución de una función sin bloquear el hilo. Para trabajar con corrutinas se utiliza la biblioteca kotlinx.coroutines. Aquí hay un ejemplo mínimo:

import kotlinx.coroutines.*

fun main() = runBlocking { launch { delay(1000L) // retardo no bloqueante println("¡Mundo!") } println("Hola,")}

En este código, runBlocking crea un contexto bloqueante para la corrutina (normalmente se usa solo en main o pruebas), y launch inicia una nueva corrutina. La función delay es una función suspend que pausa la corrutina sin bloquear el hilo.

Conceptos clave:

  • CoroutineScope — ámbito de las corrutinas, gestiona su ciclo de vida.
  • CoroutineContext — conjunto de configuraciones (dispatcher, manejador de excepciones).
  • Función suspend — función que se puede pausar y reanudar más tarde.


2. Funciones suspend y dispatchers

Las funciones suspend son la base del código asíncrono. Pueden llamar a otras funciones suspend (delay, withContext) y pausar su ejecución. Ejemplo:

suspend fun fetchUserData(): String {    delay(2000L) // simulación de solicitud de red    return "Datos del usuario"}

fun main() = runBlocking { val data = async { fetchUserData() } println("Cargando...") println(data.await()) // esperamos el resultado}

Los dispatchers determinan en qué hilo se ejecutará la corrutina:

  • Dispatchers.Default — para tareas intensivas en CPU (por defecto).
  • Dispatchers.IO — para operaciones de entrada/salida (red, archivos).
  • Dispatchers.Main — para el hilo de UI (Android, Swing).
  • Dispatchers.Unconfined — no está vinculado a un hilo específico (rara vez se usa).

Ejemplo con cambio de dispatcher:

suspend fun loadData(): String = withContext(Dispatchers.IO) {    // ejecutamos una operación pesada en un hilo de fondo    Thread.sleep(1000L) // simulación de operación bloqueante    "Resultado"}

Usar el dispatcher correcto es crítico para el rendimiento. No use Dispatchers.Main para operaciones largas: esto bloqueará la UI.



3. Trabajo con async/await y canales

Para la ejecución paralela de varias tareas, use async y await. async devuelve un objeto Deferred que se puede esperar:

fun main() = runBlocking {    val result1 = async(Dispatchers.IO) { fetchFromApi("url1") }    val result2 = async(Dispatchers.IO) { fetchFromApi("url2") }    println("Resultado 1: ${result1.await()}")    println("Resultado 2: ${result2.await()}")}

suspend fun fetchFromApi(url: String): String { delay(1000L) return "Respuesta de $url"

Blogs

Book Recommendations