Continuaciones para la interacción de tareas asincrónicas con código síncrono / Sudo Null IT News

Swift ha introducido nuevas funciones que nos ayudan a adaptar las API antiguas de estilo controlador de finalización al código asincrónico moderno.

Por ejemplo, esta función devuelve sus valores de forma asincrónica mediante un controlador de finalización:

import Foundation

func fetchLatestNews(completion: @escaping ((String)) -> Void) {
    DispatchQueue.main.async {
        completion(("Swift 5.5 release", "Apple acquires Apollo"))
    }
}

Si quisiéramos usarlo con async/await, podríamos reescribir la función, pero hay varias razones por las que esto podría no ser posible; por ejemplo, podría tomarse de una biblioteca externa.

Las continuaciones nos permiten empaquetar un controlador de finalización y funciones asíncronas para que podamos empaquetar código antiguo en una API más moderna. Por ejemplo, la función withCheckedContinuation() crea una nueva continuación que puede ejecutar cualquier código que queramos y luego llama a resume(returning:) para devolver el valor, incluso si es parte del controlador de finalización.

Entonces podemos crear una segunda función asincrónica fetchLatestNews(), envuelta alrededor de la función anterior con el controlador de finalización:

func fetchLatestNews() async -> (String) {
    await withCheckedContinuation { continuation in
        fetchLatestNews { items in
            continuation.resume(returning: items)
        }
    }
}

Ahora podemos obtener nuestra funcionalidad original en una función asíncrona como esta:

func printNews() async {
    let items = await fetchLatestNews()

    for item in items {
        print(item)
    }
}

El término continuación “comprobada” significa que Swift realiza comprobaciones en tiempo de ejecución en nuestro nombre: ¿llamamos a resume() una vez y sólo una vez? Esto es importante porque si nunca llamamos a resume() habrá una pérdida de recursos, pero si lo llamamos dos veces lo más probable es que tengamos problemas.

Importante: Debemos llamar a resume() exactamente una vez.

Debido a que verificar nuestras continuaciones tiene un costo y rendimiento en tiempo de ejecución, Swift también proporciona una función con UnsafeContinuation(), que funciona exactamente igual excepto que no realiza ninguna verificación en tiempo de ejecución. Esto significa que Swift no nos avisará si olvidamos llamar a resume(), y si lo llamamos dos veces, el comportamiento no estará definido.

Dado que estas dos funciones se llaman de la misma manera, podemos cambiar fácilmente entre ellas. Parece más probable que las personas usen withCheckedContinuation() al escribir sus funciones, por lo que Swift emitirá advertencias e incluso fallará si las continuaciones se usan incorrectamente, pero algunos pueden cambiar a withUnsafeContinuation() si el costo y el rendimiento son críticos para ellos durante la ejecución de continuaciones comprobadas.

Publicaciones Similares

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *