¿Cuál es la diferencia entre launch/join y async/await en coroutines de Kotlin?
¡Hola! Empecé a estudiar coroutines en Kotlin y me confundí con dos enfoques principales. Cuando escribo código, veo que puedo lanzar una coroutine con `launch` y luego esperar a que termine con `join()`. También existe `async` con `await()`. A primera vista hacen lo mismo: ejecutan trabajo en segundo plano y esperan el resultado. Pero siento que hay una diferencia, y es importante.
Aquí hay un ejemplo simple donde intento cargar datos de dos fuentes y combinarlos. Con launch/join me queda así:
```kotlin
fun main() = runBlocking {
var data1 = ""
var data2 = ""
val job1 = launch {
delay(1000) // simulación de carga
data1 = "Datos de API 1"
}
val job2 = launch {
delay(1000)
data2 = "Datos de API 2"
}
job1.join()
job2.join()
println("$data1 + $data2") // Funciona, pero no es bonito
}
```
Y con async/await lo hago así:
```kotlin
fun main() = runBlocking {
val deferred1 = async {
delay(10