Comprensión durante la lectura
¿Qué problema resuelve migrar de closures a async/await, y por qué se describe el problema anterior como "Closure-hell"?
El uso de closures puede ser peligroso porque:
- el desarrollador puede olvidar invocar el closure para devolver el resultado.
- Puede haber varios closures anidados lo que dificulta el mantenimiento
- El manejo de errores también es complicado, porque los datos devueltos son opcionales.
¿Cuáles son las tres opciones de refactorización que ofrece Xcode y en qué se diferencian entre sí?
-
Add Async Wrapper: Crea un método "wrapper" de tipoasync/awaitque invoca el método que usa closures. -
Add Async Alternative: Escribe una versión alternativa al método que usa closures, pero usandoasync/await. -
Convert Function to Async: Reemplaza la función en cuestión que usa closures, con otra que usaasync/await.
¿Por qué el artículo recomienda usar primero un async wrapper en lugar de reescribir directamente la lógica central?
En el caso de agregar un wrapper, o de agregar una alternativa async, el autor sugiere marcar la versión que usa closure con:
@available(*, deprecated, renamed: "fetchImage(urlRequest:)", message: "Consider using the async/await alternative.")
Una vez se ponga esa etiqueta, aparecerá un warning en los puntos clientes que se deben modificar.
Esto permite concentrarse en reescribir la sintaxis async/await en el código de producción y en las pruebas, en lugar de preocuparse por la correcta conversión de la lógica asíncrona.
** LO MAS IMPORTANTE ES RESCRIBIR PRIMERO LAS PRUEBAS PARA QUE USEN EL WRAPPER ASYNC/AWAIT **
¿Qué dos reglas críticas hay que respetar al usar withCheckedThrowingContinuation?
-
Hacer "resume" exactamente una vez: 0 veces provoca una fuga. Más de 1, provoca un error en tiempo de ejecución. La variante "checked" (i.e.
withCheckedThrowingContinuation) atrapa doble "resume"s en tiempo de desarrollo. - Evitar deadlocks: Si el closure que se pasa al "continuation" está esperando a algo que solo ocurre después del "resume", entonces aparece un "deadlock".
¿Por qué las herramientas de refactorización automática de Xcode no siempre producen el resultado óptimo?
A veces, a pesar de que la firma del método pasa a ser async/await, internamente puede usar una aproximación basada en closures, por lo que no termina siendo un refactor muy efectivo.
Al leer el código de ImageFetcher, ¿qué rol cumple el bloque do-catch dentro del closure de URLSession?
Captura un error en el catch y lo arroja con el "continuation".
¿Cómo cambia la implementación final de ImageFetcherMigrated respecto a las versiones intermedias generadas por Xcode?
Las versiones intermedias igual hacían la petición con URLSession usando closures. La versión final de ImageFetcherMigrated usa URLSession con su versión async (i.e. await URLSession.shared.data(for: urlRequest)).
Top comments (0)