/* Page prose (es) */
"ClassicVsModernWrappingUp" = "# Resumen\n\nAhora has visto una tarea cotidiana (obtener dos cosas, combinarlas, manejar errores, entregar en el principal) resuelta de ambas formas, y la versión moderna gana en legibilidad, seguridad y puro número de líneas. La conclusión honesta no es \"reescribe todo,\" sin embargo; es saber qué se mapea a qué, y dónde migrar de verdad rinde. El resumen de abajo es un mapa para ambas cosas.\n\n* El modelo moderno gana en la misma tarea: sin estado mutable compartido, sin `enter`/`leave`, un solo camino de error, y un salto automático al hilo principal vía `@MainActor`.\n* Toda herramienta clásica tiene una contraparte moderna:\n  * completion handler ➡️ función `async`\n  * `DispatchGroup`/semáforo ➡️ `async let`/`TaskGroup`\n  * protección con cola serial ➡️ **actor**\n  * `DispatchQueue.main` ➡️ **`@MainActor`**\n  * cancelación manual de `Operation` ➡️ cancelación cooperativa de `Task`\n  * delegado/callback ➡️ `AsyncStream`/continuación\n* **Lo clásico todavía se gana su lugar** para APIs más antiguas, control de despacho fino, objetivos de SO anteriores a `async`/`await`, y código que ya funciona: una reescritura es un costo, así que la trampa es gastarlo donde no hay recompensa.\n* **Migra en las costuras:** envuelve los callbacks heredados con continuaciones, escribe el código nuevo moderno, reemplaza los bloqueos ad-hoc con actores, adopta `@MainActor` para la UI, y activa la comprobación de carreras de datos de Swift 6 de forma incremental.\n* **Puentea la frontera con cuidado:** una continuación se reanuda **exactamente una vez**, así que un callback que se dispara muchas veces necesita un `AsyncStream`. Y nunca bloquees con `DispatchGroup.wait()`/`semaphore.wait()` dentro de una `Task`: puentea con una continuación y hazle `await` en su lugar.\n* **`@MainActor` no mueve tu trabajo lento**: garantiza que el código anotado se ejecute en el principal. Haz el trabajo pesado en una función asíncrona simple fuera del principal, y reserva la parte `@MainActor` para la pequeña actualización de UI al final.\n* Los dos modelos **interoperan**: el código mixto es normal y esperable durante una migración.\n\n---\n\n## Adónde ir después\n\nEse es todo el libro: desde un solo barista bloqueado en el hilo principal hasta actores que mantienen seguro el estado compartido dentro de un solo proceso. Has conocido el modelo clásico (GCD y Operations) y el moderno (`async`/`await`, concurrencia estructurada, `AsyncSequence` y actores), y has visto *por qué* el segundo existe como respuesta al primero.\n\nLos conceptos solo se asientan de verdad una vez que los usas en algo que te importa. Así que aquí va el ánimo para cerrar: **abre uno de tus propios proyectos y vuelve a visitar los capítulos modernos.** Encuentra un completion handler y conviértelo en `async`/`await`. Encuentra un valor mutable compartido protegido por un cerrojo y hazlo un `actor`. Encuentra una pantalla que da tirones y saca su trabajo pesado del hilo principal. Cada pequeño cambio hará que un capítulo encaje en su sitio para siempre.\n\nLa concurrencia deja de dar miedo en el momento en que la has hecho funcionar, a propósito, en código que es tuyo. Ve y hazlo. Estás listo.\n\n---\n\n## Pista extra: actores entre máquinas\n\n¿Con curiosidad de hasta dónde se estira la idea de actor? Hay un capítulo más después de este, **[Actores distribuidos](Distributed%20Actors.playgroundchapter/Overview)**, como crédito extra. Lleva la misma sensación de `await`-para-llamar hacia objetos que viven en *otros procesos, incluso en otras máquinas*. Es un recorrido conceptual de lectura en lugar de un laboratorio ejecutable, así que trátalo como un vistazo hacia adelante para cuando las ideas centrales se sientan sólidas.\n\n[Anterior](@previous)  |  página 8 de 8";
