52 - Corrutinas: funciones de suspensión (suspend fun)

Una función de suspensión solo puede ser llamada desde una corrutina o desde otra función de suspensión.

Las funciones de suspensión llamadas desde una corrutina se ejecutan en forma secuencial por defecto, por ejemplo probemos el siguiente código que llama a dos funciones de suspensión:

import kotlinx.coroutines.*

fun main(args: Array<String>) = runBlocking {
    val d1=dato1()
    println("Fin de la primera función de suspensión")
    val d2=dato2()
    println("Fin de la segundo función de suspensión")
    print(d1+d2)
}

suspend fun dato1(): Int {
    delay(3000)
    return 3
}

suspend fun dato2(): Int {
    delay(3000)
    return 3
}

Cuando ejecutamos la aplicación, luego de 4 segundos de su ejecución podemos ver que ha finalizado la función de suspensión 'dato1' y se encuentra ahora ejecutando la función de suspensión 'dato2':

Coroutines runBlocking función de suspensión

En muchas situaciones las llamadas secuenciales de las funciones de suspensión son la solución correcta, por ejemplo solicitamos a un servidor un dato y a partir de dicho dato hacemos la petición a otro servidor a partir del dato recuperado del primer servidor.

El tiempo de ejecución de las dos funciones de suspensión es aproximadamente de 6 segundos, esto debido a que se ejecutan en forma secuencial.

Llamadas concurrentes.

En algunas situaciones si el problema lo permite podemos ejecutar las funciones de suspensión en forma concurrente y eventualmente si disponemos de varios procesadores la ejecución se puede hacer en paralelo con la ventaja de reducir el tiempo. Veamos la sintaxis para implementar las llamadas a funciones de suspensión en forma concurrente:

import kotlinx.coroutines.*

fun main(args: Array<String>) = runBlocking {
    val tiempo1 = System.currentTimeMillis()
    val corrutina1=async { dato1() }
    val corrutina2=async { dato2() }
    println(corrutina1.await()+corrutina2.await())
    val tiempo2 = System.currentTimeMillis()
    println("Tiempo total ${tiempo2-tiempo1}")
}

suspend fun dato1(): Int {
    delay(3000)
    return 3
}

suspend fun dato2(): Int {
    delay(3000)
    return 3
}
Coroutines runBlocking función de suspensión concurrentes

Como podemos comprobar las dos funciones se ejecutan en forma paralela y por eso el tiempo de ejecución del algoritmo es de 3 segundos.