launch — esencia, lanzamiento fire-and-forget de corrutinas y cómo funciona

Autor: IT Sectr Publicado: 2026-06-22 Tiempo de lectura: 7 min

launch — un Coroutine Builder en Kotlin que inicia una corrutina sin devolver un resultado, retornando un objeto Job para controlar la ejecución. Este builder implementa el patrón fire-and-forget: la corrutina comienza a trabajar en un hilo de fondo y finaliza automáticamente. Según la documentación de JetBrains, 2024, launch es la forma principal de ejecutar tareas paralelas en Kotlin Coroutines.

Puntos clave

  • launch — un builder para iniciar corrutinas sin devolver resultado (fire-and-forget)
  • Job — un objeto de control de corrutina con métodos cancel(), join(), isActive
  • launch se integra con CoroutineScope para cancelación automática de corrutinas hijas
  • CoroutineStart.LAZY permite diferir la ejecución hasta una llamada explícita a start() o join()
  • launch en Android se usa para guardar en BD, llamadas de red y actualizaciones de UI

¿Qué es launch en Kotlin Coroutines?

launch es una función de extensión de Kotlin, disponible mediante la importación de kotlinx.coroutines, que crea una nueva corrutina en un CoroutineScope dado. A diferencia de las funciones normales, el código dentro de launch se ejecuta concurrentemente — la corrutina puede suspenderse sin bloquear un hilo y reanudarse más tarde.

El builder launch es un bloque fundamental del modelo de corrutinas de Kotlin. No devuelve un valor calculado pero retorna un objeto Job que permite controlar la ejecución de la corrutina. Todas las corrutinas hijas lanzadas mediante launch dentro de otra corrutina están vinculadas a la padre.

Sintaxis y parámetros de launch

El builder launch se define como una función inline con varios parámetros: CoroutineScope, CoroutineContext, CoroutineStart y un bloque suspend. Los parámetros tienen valores por defecto, lo que hace que launch sea conveniente para escenarios típicos.

kotlin
public fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> Unit
): Job

El parámetro context acepta un CoroutineContext que combina un dispatcher, un manejador de excepciones y un elemento con nombre. Lo más frecuente es pasar Dispatchers.IO, Dispatchers.Main o SupervisorJob para aislar errores.

Job y gestión del ciclo de vida

Job — el objeto devuelto que representa el ciclo de vida de la corrutina. Un Job puede estar en estados: New, Active, Completing, Completed, Cancelling, Cancelled. Cada estado refleja el estado de ejecución y permite reaccionar a los cambios.

kotlin
val job = CoroutineScope(Dispatchers.IO).launch {
    repeat(10) { i ->
        delay(1000L)
        println("Progreso: $i")
    }
}

println("El trabajo está activo: ${job.isActive}")
delay(2500L)
job.cancel()
println("El trabajo está cancelado: ${job.isCancelled}")

Job soporta una jerarquía: si una corrutina padre es cancelada, todas las hijas se cancelan automáticamente. SupervisorJob cambia este comportamiento — las corrutinas hijas no se cancelan cuando una de ellas falla.

Concurrencia estructurada en launch

La concurrencia estructurada significa que cada corrutina se lanza dentro de un CoroutineScope específico, y el scope no se completa hasta que todas las corrutinas hijas terminan su trabajo. launch soporta completamente este principio — las corrutinas lanzadas dentro de otra corrutina son sus hijas.

Llamadas launch anidadas

Con llamadas launch anidadas, se forma un árbol de corrutinas. La corrutina padre espera a que todas las hijas se completen, garantizando un orden de ejecución predecible y simplificando la gestión de recursos.

kotlin
fun main() = runBlocking {
    launch {
        launch {
            delay(1000L)
            println("Hijo 1 completado")
        }
        launch {
            delay(500L)
            println("Hijo 2 completado")
        }
        println("Todos los hijos completan antes de esta línea")
    }
}

Este comportamiento difiere de la concurrencia basada en hilos, donde los hilos hijos no están vinculados al padre. En las corrutinas, el padre no se completa hasta que todos los hijos terminan su trabajo.

Manejo de excepciones en launch

El manejo de excepciones en launch depende del tipo de Job. Para un Job normal, las excepciones se propagan a la corrutina padre y la cancelan. Para SupervisorJob o SupervisorScope, las excepciones se aíslan — un error en una corrutina hija no afecta a las demás.

kotlin
val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
scope.launch {
    try {
        riskyOperation()
    } catch (e: Exception) {
        println("Capturado: ${e.message}")
    }
}
scope.launch {
    println("Esto aún funciona gracias a SupervisorJob")
}

Para el manejo global de excepciones no capturadas, se usa CoroutineExceptionHandler. Captura las excepciones que no fueron manejadas dentro de la corrutina y permite registrar el error sin bloquear la aplicación.

Ejemplos de uso de launch en Android

En Android, launch se usa en todas partes: desde ViewModel hasta WorkManager. El patrón principal es usar lifecycleScope en Fragment y viewModelScope en ViewModel para la cancelación automática de corrutinas al finalizar el ciclo de vida del componente.

kotlin
class ProfileViewModel : ViewModel() {
    private val repository = UserRepository()

    fun loadProfile(userId: String) {
        viewModelScope.launch(Dispatchers.IO) {
            val profile = repository.fetchProfile(userId)
            withContext(Dispatchers.Main) {
                _profileState.update { it.copy(profile = profile) }
            }
        }
    }
}

viewModelScope cancela automáticamente las corrutinas cuando la ViewModel se destruye. Esto elimina fugas y asegura que las operaciones en segundo plano no continúen después de perder el contexto. Adicionalmente, se puede usar withContext para cambiar entre dispatchers.

Preguntas frecuentes

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

launch devuelve un Job y no retorna un resultado, mientras que async devuelve Deferred<T> para obtener el resultado. launch se usa para operaciones fire-and-forget, async — cuando necesitas esperar y usar el valor devuelto.

¿Cómo cancelar una corrutina lanzada mediante launch?

Llama a job.cancel() en el objeto Job guardado. Para cancelación grupal, cancela todo el CoroutineScope mediante scope.cancel(). La corrutina debe ser cooperativa — verificar isActive o usar funciones suspend cancelables.

¿Qué hacer si launch lanza una excepción?

Usa try-catch dentro del bloque launch o pasa CoroutineExceptionHandler en el CoroutineContext. Para aislar errores, usa SupervisorJob — entonces una excepción en una corrutina hija no cancelará las demás.

¿Se puede usar launch sin CoroutineScope?

No, launch es una función de extensión de CoroutineScope. Sin un scope, la corrutina no puede seguir el principio de concurrencia estructurada. Usa GlobalScope.launch con precaución — crea una corrutina sin vinculación al ciclo de vida.

¿Cuántas corrutinas launch pueden ejecutarse simultáneamente?

El número está limitado por el pool de hilos del dispatcher. Dispatchers.Default usa tantos hilos como núcleos de CPU. Dispatchers.IO soporta hasta 64 hilos. Si se lanzan más corrutinas, se ponen en cola.

Resumen

  • launch — el builder principal para corrutinas fire-and-forget, que devuelve un objeto Job
  • Job proporciona métodos de control: cancel(), join(), isActive, isCancelled, isCompleted
  • Concurrencia estructurada garantiza la cancelación de corrutinas hijas al cancelar la padre
  • Manejo de excepciones depende del tipo de Job: el normal propaga errores, SupervisorJob los aísla
  • lifecycleScope y viewModelScope — soluciones listas para lanzar corrutinas en Android
  • CoroutineStart.LAZY difiere la ejecución hasta una llamada explícita a start() o join()
  • launch en Android se usa para peticiones de red, escritura en BD, analítica y caché

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