Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

253
Vistas
Comportamiento extraño de Kotlin con chunked, async y await

Estoy haciendo un código que involucra una cantidad de solicitudes paralelas en lotes de elementos en una lista y me encuentro con un comportamiento extraño:

 import kotlinx.coroutines.* suspend fun main() { coroutineScope { val hello = listOf("hello", "world") val chunks = hello.chunked(1) { async { translate(it.first()) } } chunks.forEach { print(it.await()) } } } private fun translate(word: String): String { return if(word == "hello") { "hola" } else { "mundo" } }

Debería mostrar "holamundo", pero a veces este ejemplo imprime "mundomundo" en su lugar.

También lo puse a disposición en Kotlin Playground .

¿Qué me estoy perdiendo aquí?

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

El motivo de este comportamiento es que el código dentro de async no se ejecuta inmediatamente. Solo está programado. El bloque async regresa antes de que se invoque la lambda. Esta es la razón por la it el bloque async interno siempre apunta a la ventana ["world"] y, por lo tanto, la salida final es "mundomundo".

Toma este ejemplo:

 fun main() { runBlocking { var a = 1 val deferred = async { println(a) } a++ deferred.await() } }

Patio de recreo
En este ejemplo, la salida será 2 y no 1 porque a++ se procesa antes que la lambda async .

Editar: como señaló @ IR42 en el comentario, la documentación menciona claramente que la lista pasada a la función de transformación cambia muy rápidamente, por lo que si desea usarla de forma asíncrona, primero debe hacer una copia de ella.

 val chunks = hello.chunked(1) { val copy = it.toList() async { translate(copy.first()) } }

Este código le dará el resultado esperado.

Otra solución (gracias a @broot) es calcular primero la lista fragmentada completa y luego asignarla a la lista de diferidos.

 val chunks = hello.chunked(1).map { async { translate(it.first()) } }
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda