Coroutines y asincronía

Kotlin
Kotlin
Actualizado: 30/06/2025

¡Desbloquea el curso completo!

IA
Ejercicios
Certificado
Entrar

Coroutines y asincronía en Kotlin

La programación asíncrona representa uno de los paradigmas más importantes en el desarrollo moderno de aplicaciones. En lugar de ejecutar operaciones de forma secuencial y bloqueante, permite que el programa continúe ejecutando otras tareas mientras espera que se completen operaciones lentas como llamadas a APIs, acceso a bases de datos o lectura de archivos.

Kotlin introduce las coroutines como su solución nativa para la programación asíncrona, ofreciendo una alternativa elegante y eficiente a los callbacks tradicionales y los threads. Las coroutines permiten escribir código asíncrono que se lee de forma secuencial, eliminando la complejidad típica asociada con la gestión manual de hilos.

¿Qué son las coroutines?

Las coroutines son funciones que pueden suspender su ejecución en puntos específicos y reanudarla posteriormente sin bloquear el hilo en el que se ejecutan. Esta capacidad de suspensión es fundamental para crear aplicaciones eficientes que no desperdicien recursos del sistema.

A diferencia de los threads tradicionales, que son costosos de crear y mantener, las coroutines son extremadamente ligeras. Es posible ejecutar miles de coroutines simultáneamente sin impacto significativo en el rendimiento, algo impensable con threads convencionales.

import kotlinx.coroutines.*

fun main() {
    runBlocking {
        launch {
            delay(1000L) // Suspende por 1 segundo sin bloquear
            println("Mundo!")
        }
        println("Hola ")
    }
}

En este ejemplo, delay() es una función suspendible que pausa la ejecución de la coroutine sin bloquear el hilo principal, permitiendo que otras operaciones continúen.

Funciones suspendibles

Las suspend functions son el corazón de las coroutines en Kotlin. Estas funciones pueden pausar su ejecución y ceder el control a otras coroutines, optimizando el uso de recursos del sistema.

suspend fun obtenerDatos(): String {
    delay(2000L) // Simula una operación lenta
    return "Datos obtenidos"
}

suspend fun procesarDatos(datos: String): String {
    delay(1000L) // Simula procesamiento
    return "Procesado: $datos"
}

Las funciones suspendibles solo pueden ser llamadas desde otras funciones suspendibles o desde dentro de una coroutine. Esta restricción garantiza que el mecanismo de suspensión funcione correctamente.

Builders de coroutines

Guarda tu progreso

Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.

Progreso guardado
Asistente IA
Ejercicios
Iniciar sesión gratis

Más de 25.000 desarrolladores ya confían en CertiDevs

Kotlin proporciona varios builders para crear y gestionar coroutines, cada uno con propósitos específicos:

runBlocking crea una coroutine que bloquea el hilo actual hasta que todas las coroutines internas completan su ejecución:

fun main() = runBlocking {
    val resultado = obtenerDatos()
    println(resultado)
}

launch inicia una nueva coroutine de forma concurrente, ideal para operaciones que no necesitan devolver un resultado:

runBlocking {
    launch {
        repeat(5) { i ->
            println("Coroutine A: $i")
            delay(500L)
        }
    }
    
    launch {
        repeat(3) { i ->
            println("Coroutine B: $i")
            delay(800L)
        }
    }
}

async permite ejecutar operaciones concurrentes que devuelven resultados, facilitando la programación paralela:

runBlocking {
    val deferred1 = async { obtenerDatos() }
    val deferred2 = async { obtenerDatos() }
    
    val resultado1 = deferred1.await()
    val resultado2 = deferred2.await()
    
    println("$resultado1 y $resultado2")
}

Contextos y dispatchers

Los dispatchers determinan en qué hilos se ejecutan las coroutines, proporcionando control granular sobre el rendimiento y comportamiento de la aplicación:

Dispatchers.Main ejecuta coroutines en el hilo principal de la interfaz de usuario:

launch(Dispatchers.Main) {
    // Actualizar UI
    textView.text = "Cargando..."
}

Dispatchers.IO está optimizado para operaciones de entrada/salida como llamadas de red o acceso a archivos:

launch(Dispatchers.IO) {
    val datos = descargarDatos()
    withContext(Dispatchers.Main) {
        mostrarDatos(datos)
    }
}

Dispatchers.Default utiliza un pool de hilos optimizado para operaciones intensivas de CPU:

launch(Dispatchers.Default) {
    val resultado = calcularOperacionCompleja()
    // Procesar resultado
}

Gestión de errores

Las coroutines integran el manejo de excepciones de forma natural usando try-catch tradicional:

runBlocking {
    try {
        val datos = async { obtenerDatosRiesgosos() }
        val resultado = datos.await()
        println(resultado)
    } catch (e: Exception) {
        println("Error: ${e.message}")
    }
}

Para operaciones concurrentes, es importante considerar que las excepciones en coroutines creadas con launch se propagan al CoroutineScope padre, mientras que las creadas con async encapsulan las excepciones hasta que se llama a await().

Cancelación de coroutines

La cancelación cooperativa permite detener coroutines de forma controlada y eficiente:

runBlocking {
    val job = launch {
        repeat(1000) { i ->
            if (!isActive) return@launch // Verificar cancelación
            println("Trabajando: $i")
            delay(100L)
        }
    }
    
    delay(500L)
    job.cancel() // Cancelar la coroutine
    job.join()   // Esperar a que termine
}

Las coroutines deben cooperar en su cancelación verificando regularmente su estado o usando funciones suspendibles que respeten la cancelación automáticamente.

Completa Kotlin y certifícate

Únete a nuestra plataforma y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.

Asistente IA

Resuelve dudas al instante

Ejercicios

Practica con proyectos reales

Certificados

Valida tus conocimientos

Más de 25.000 desarrolladores ya se han certificado con CertiDevs

⭐⭐⭐⭐⭐
4.9/5 valoración