Coroutine Builder: qué es, tipos de constructores de corrutinas y cómo funcionan

Autor: IT Sectr Publicado: 2026-06-21 Tiempo de lectura: 8 min

Coroutine Builder — funciones de Kotlin Coroutines que crean y lanzan corrutinas, definiendo cómo se ejecutan. Los constructores launch, async, runBlocking y produce cubren diferentes escenarios: desde tareas en segundo plano hasta cómputos paralelos con devolución de resultados. Según JetBrains, 2024, Coroutine Builder es la base del modelo de corrutinas, proporcionando concurrencia estructurada y gestión del ciclo de vida.

Puntos clave

  • Coroutine Builder — una función que crea una corrutina dentro de un CoroutineScope específico
  • launch — lanza una corrutina sin devolver un resultado, devuelve un objeto Job
  • async — lanza una corrutina devolviendo Deferred, permitiendo obtener el resultado mediante await()
  • runBlocking — bloquea el hilo actual, usado como puente entre código bloqueante y suspendido
  • produce — crea una corrutina con un canal para transmisión de datos (obsoleto en favor de Flow)

¿Qué es un Coroutine Builder?

Coroutine Builder es una función de extensión de Kotlin que toma un CoroutineScope y un bloque suspend, creando y lanzando una nueva corrutina. Cada constructor define cómo se ejecutará la corrutina: con o sin devolución de resultado, con bloqueo de hilo o asíncronamente. Los constructores son los puntos de entrada al modelo de corrutinas del lenguaje.

Todos los constructores trabajan a través de CoroutineScope, que gestiona el ciclo de vida de las corrutinas hijas. Cuando se cancela un scope, todas las corrutinas lanzadas a través de él se cancelan automáticamente — este es el principio de concurrencia estructurada. Este enfoque previene fugas de corrutinas y garantiza una finalización predecible.

kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    // Los builders se ejecutan dentro de CoroutineScope
    val job = launch {
        delay(1000L)
        println("¡Mundo!")
    }
    println("Hola,")
    job.join()
}

Tipos principales de constructores de corrutinas

Kotlin proporciona cuatro constructores de corrutinas incorporados: launch, async, runBlocking y produce. Cada uno tiene su propio tipo de retorno y área de aplicación. Para desarrollo móvil Android, los principales son launch y async — funcionan de manera no bloqueante y se integran con componentes arquitectónicos.

ConstructorTipo de retornoBloqueo de hiloEscenario
launchJobNoTareas fire-and-forget
asyncDeferred<T>NoCómputos paralelos
runBlockingTTests, función main
produceReceiveChannel<E>NoTransmisión (obsoleto)

Cada constructor acepta parámetros adicionales: CoroutineStart (estrategia de lanzamiento), CoroutineContext (despachador, excepciones) y un bloque de código nombrado. Por defecto, la corrutina se inicia inmediatamente (CoroutineStart.DEFAULT).

launch: ejecución fire-and-forget

launch es el constructor más utilizado en desarrollo Android. Lanza una corrutina que no devuelve un resultado, y devuelve un objeto Job para gestionar su ciclo de vida. Es la elección ideal para operaciones que solo necesitan un efecto secundario: guardar en base de datos, enviar analíticas, actualizar la UI.

Sintaxis y uso de launch

El constructor launch acepta CoroutineScope, un CoroutineContext opcional y un bloque suspend. El Job devuelto permite cancelar la corrutina, esperar su finalización o verificar su estado.

kotlin
val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
val job: Job = scope.launch(CoroutineStart.LAZY) {
    val data = fetchFromNetwork()
    saveToDatabase(data)
}
job.start()
job.join()

El parámetro CoroutineStart.LAZY aplaza la ejecución hasta una llamada explícita a start() o join(). Esto es útil para inicialización diferida y ejecución condicional. Para ejecución inmediata estándar se usa CoroutineStart.DEFAULT o se omite el parámetro.

async: cómputos paralelos con resultado

async es un constructor que devuelve Deferred<T> — una promesa asíncrona de un resultado. Llamar a await() suspende la corrutina hasta obtener el resultado, sin bloquear el hilo. Es el mecanismo principal para tareas paralelas en corrutinas Kotlin.

Lanzando dos solicitudes en paralelo

async es especialmente efectivo cuando necesitas ejecutar múltiples operaciones independientes simultáneamente. A diferencia de las llamadas secuenciales a funciones suspend, async lanza corrutinas en paralelo, reduciendo el tiempo total de ejecución.

kotlin
suspend fun fetchUserData(): UserData {
    val deferred1 = CoroutineScope(Dispatchers.IO).async { api.getProfile() }
    val deferred2 = CoroutineScope(Dispatchers.IO).async { api.getSettings() }
    val deferred3 = CoroutineScope(Dispatchers.IO).async { api.getNotifications() }
    return UserData(
        profile = deferred1.await(),
        settings = deferred2.await(),
        notifications = deferred3.await()
    )
}

Deferred hereda de Job, por lo que async soporta todas las operaciones del ciclo de vida: cancelación, espera de finalización, manejo de excepciones. Cuando se cancela un scope, las corrutinas Deferred hijas se cancelan automáticamente.

runBlocking: puente al mundo bloqueante

runBlocking es el único constructor que bloquea el hilo actual hasta que la corrutina finaliza. Crea un nuevo CoroutineScope y lanza la corrutina pasada, bloqueando el hilo llamante. Se usa en puntos de entrada main(), en tests y al integrar con código bloqueante.

Cuándo es necesario runBlocking

runBlocking está justificado en tres escenarios: el punto de entrada de la aplicación (main), tests unitarios de funciones suspend y la integración con bibliotecas basadas en callbacks donde no se puede usar suspend. En código Android de producción, usar runBlocking en el hilo principal no está recomendado.

kotlin
class CoroutineTest {
    @Test
    fun `test suspend function`() = runBlocking {
        val result = mySuspendFunction()
        assertEquals("expected", result)
    }
}

Para tests se recomienda usar kotlinx-coroutines-test con TestCoroutineDispatcher en lugar de runBlocking — esto proporciona control del tiempo y evita bloqueos en el entorno de pruebas.

Cómo elegir el constructor adecuado

La elección del Coroutine Builder depende del resultado devuelto y del escenario de ejecución. Si la operación no requiere devolver datos — usa launch. Si necesitas el resultado de una operación asíncrona — usa async. runBlocking solo debe usarse como puente, y reemplaza produce por Flow para flujos reactivos.

Recomendaciones prácticas para Android

En proyectos Android que usan Kotlin Coroutines, el par principal de constructores son launch y async. launch se usa en ViewModel y UseCases para lanzar corrutinas, mientras que async se usa para solicitudes paralelas a la red o base de datos. Las bibliotecas modernas (Ktor, Room) ya soportan funciones suspend, lo que minimiza la necesidad de uso directo de async.

  • launch — para fire-and-forget (logging, analíticas, caché)
  • async — para solicitudes paralelas con combinación de resultados
  • runBlocking — solo en main() y tests (no en el hilo Main en producción)
  • produce — reemplazar por Flow / SharedFlow / StateFlow

Preguntas frecuentes

¿Cuál es la diferencia entre launch y async en Kotlin?

launch devuelve Job y no devuelve un resultado de ejecución, mientras que async devuelve Deferred<T> — un objeto del que se puede obtener el resultado mediante await(). launch se usa para operaciones fire-and-forget, async para tareas que devuelven datos.

¿Se puede usar runBlocking en una Activity de Android?

No se recomienda. runBlocking en el hilo principal causa ANR y bloquea la UI. Usa lifecycleScope.launch dentro de Activity y Fragment — es una solución incorporada sin bloqueos.

¿Qué devuelve el constructor launch?

El constructor launch devuelve un objeto Job, que permite controlar el ciclo de vida de la corrutina: cancelar (cancel), esperar finalización (join), verificar estado (isActive, isCompleted, isCancelled).

¿Qué es Deferred en Kotlin Coroutines?

Deferred<T> es una promesa asíncrona de un resultado, devuelta por el constructor async. Hereda de Job y añade métodos await() para obtener el resultado, getCompleted() para acceso no bloqueante y getCompletionExceptionOrNull() para verificar excepciones.

¿Cómo lanzar launch con retraso?

Usa el parámetro CoroutineStart.LAZY: scope.launch(start = CoroutineStart.LAZY) { ... }. Luego llama a job.start() o job.join() para la ejecución real. Esto es útil para inicialización diferida y ejecución condicional de corrutinas.

Resumen

  • Coroutine Builder — una función de creación de corrutinas que define cómo se ejecuta y su tipo de retorno
  • launch — el constructor principal para tareas sin resultado, devuelve Job para gestión de la corrutina
  • async — constructor para cómputos paralelos, devuelve Deferred con posibilidad de await() del resultado
  • runBlocking — constructor bloqueante para main() y tests, no recomendado en el hilo principal de Android
  • Concurrencia estructurada garantiza la cancelación automática de corrutinas hijas al cancelar el scope
  • produce está obsoleto — usa Flow, SharedFlow o StateFlow para flujos de datos reactivos
  • La elección del constructor depende del escenario: fire-and-forget → launch, datos paralelos → async, bridging → runBlocking

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también