Mezclando código síncrono y asíncrono usando CheckedContinuation

Es un mecanismo que nos permite crear un puente entre código síncrono y asíncrono.

func withCheckedContinuation<T>(
function: String = #function,
_ body: (CheckedContinuation<T, Never>) -> Void
) async -> T

Esta es la firma de withCheckedContinuation(function:_:), veamos los parámetros que requiere:

  • function, se utiliza para identificar la función donde se está usando el Continuation, esto permite identificar el Continuation para los análisis que se realizan en tiempo de ejecución.
  • body, este parámetro acepta un closure de tipo (CheckedContinuation<T, Never>) -> Void. Este será el bloque de código que ejecutaremos de manera síncrona como parte del Continuation.
  • Nota que esta función es genérica y puede retornar cualquier tipo.

¿Cómo usar Continuation?

Uno de los usos de Continuation es para convertir código que usa completion handlers en código compatible con async/await.

A continuación veamos un ejemplo de como podemos usar esta herramienta:

func decodeData(_ encodedData: [EncodedInfo],
completion: @escaping ([Info]) -> Void) {
// Realiza un procesamiento
// Luego retorna un arreglo de objetos Info usando el completion handler.
}

Esta función luego de hacer un procesamiento retorna el resultado utilizando un completion handler.

Para poder hacer uso de esta función con async/await, usamos el siguiente código:

func decodeData(_ encodedData: [EncodedInfo]) async -> [Info] {
await withCheckedContinuation { continuation in
decodeData(encodedData) { decodedInfo in
continuation.resume(returning: decodedInfo)
}
}
}

Envolvemos el código que usa completion handlers dentro de un withCheckedContinuation y llamamos la función:

decodeData(_ encodedData: [EncodedInfo],
completion: @escaping ([Info]) -> Void)

Por último, utilizamos el continuation para resumir la tarea y retornar decodedInfo:

continuation.resume(returning: decodedInfo)

Maneras de resumir un Continuation

Dependiendo del tipo de Continuation que estemos usando, podemos utilizar los siguientes métodos para reanudar las tareas:

  • resume(returning:) se utiliza en el ejemplo y reanuda la ejecución de la tarea devolviendo un valor.
  • resume(throwing:) reanuda la tarea emitiendo una excepción desde el punto de suspensión.
  • resume(with:) reanuda la ejecución de la tarea devolviendo un Result<T, E> lo que significa que puede devolver un valor o un error.
  • resume() reanuda la ejecución de la tarea sin devolver nada.

Otros Continuations disponibles

Hay otros tipos de Continuation que tenemos a nuestra disposición:

  • withUnsafeContinuation(_:) y UnsafeThrowingContinuation(_:): Son alternativas a withCheckedThrowingContinuation(_:) y withCheckedContinuation(_:), que no realizan ninguna verificación o diagnóstico en tiempo de ejecución. Debemos tener mucho cuidado cuando usamos APIs Unsafe, puesto que queda en nosotros asegurarnos de que el código no presenta fallos. Por ejemplo, asegurarnos de no llamar resume más de una vez.
  • withCheckedThrowingContinuation(_:): Este es similar a withCheckedContinuation(_:), pero puede emitir excepciones.

Cosas a tener en cuenta cuando usamos Continuations

Aquí algunas consideraciones importantes al utilizar Continuations:

  • El código que se pasa en body se ejecuta de manera síncrona dentro de la tarea desde la cual se llama. Una vez que la tarea retorna, se suspende. Por lo tanto, debemos asegurarnos de llamar a resume utilizando una de las formas disponibles.
  • Solo debes llamar a uno de los métodos resume una vez dentro de una ejecución.
  • Si no llamas a resume, puede haber fugas de memoria y la tarea desde la cual se creó la Continuation se mantendrá suspendida indefinidamente.
  • Intentar resumir una Continuation más de una vez provocará un error en la ejecución.
  • A menos que estemos seguros de que el rendimiento se ve significativamente mejorado al usar UnsafeContinuation, es recomendable utilizar CheckedContinuation.

Comparte este artículo

Subscríbete a nuestro Newsletter

Mantente al día en el mundo de las aplicaciones móviles con nuestro blog especializado.

Artículos semanales

Todas las semanas artículos nuevos sobre el mundo de las aplicaciones móviles.

No spam

No te enviaremos spam, solo contenido de calidad. Puedes darte de baja cuando quieras.

Contenido de calidad

Nada de contenido generado de manera automática usando ChatGPT.

Recomendaciones

Tips indispensables sobre mejores prácticas y metodologías.

© 2024 AsyncLearn