¿Qué es la programación asíncrona y por qué la necesitas?
La programación asíncrona permite ejecutar múltiples operaciones simultáneamente sin tener que esperar a que cada una termine. Esto es fundamental para crear aplicaciones de alto rendimiento que no se bloquean al realizar operaciones lentas.
Principales ventajas de la asincronía
La asincronía es especialmente efectiva en estos escenarios:
- Peticiones de red (solicitudes HTTP, trabajo con REST API)
- Operaciones con el sistema de archivos (lectura y escritura de archivos grandes)
- Interacción con bases de datos (consultas SQL, operaciones NoSQL)
- Conexiones WebSocket y aplicaciones en tiempo real
- Web scraping y extracción de datos
- Procesamiento de colas de mensajes
Introducción a la librería asyncio
asyncio es la librería estándar de Python para escribir código asíncrono basado en un bucle de eventos (event loop). Forma parte de Python desde la versión 3.4 y se mejoró significativamente en las versiones 3.7+.
Funcionalidades clave de asyncio
Con asyncio puedes:
- Crear y gestionar corrutinas
- Ejecutar múltiples tareas asíncronas en paralelo
- Manejar eficientemente miles de conexiones simultáneas
- Integrarte con librerías y frameworks asíncronos
Conceptos fundamentales de asyncio
Corrutinas (Coroutines)
Una corrutina es una función especial que puede pausarse y reanudarse más tarde. En Python, las corrutinas se definen con la palabra clave async def.
import asyncio
async def saludar():
print("¡Hola!")
await asyncio.sleep(1)
print("Pasó 1 segundo.")
# Ejecutar la corrutina
asyncio.run(saludar())
La palabra clave await
await se usa para pausar la ejecución de una corrutina hasta que otra operación asíncrona termine. Es el mecanismo clave para devolver el control al event loop.
async def mensaje_con_retraso():
print("Inicio de ejecución")
await asyncio.sleep(2)
print("Mensaje después de 2 segundos")
asyncio.run(mensaje_con_retraso())
Event Loop (Bucle de eventos)
El Event Loop es el corazón de asyncio, el mecanismo que gestiona la ejecución de todas las tareas asíncronas. Desde Python 3.7, se recomienda usar asyncio.run() para ejecutar código asíncrono.
# Forma moderna (Python 3.7+)
asyncio.run(corrutina_principal())
# Forma antigua (antes de Python 3.7)
loop = asyncio.get_event_loop()
loop.run_until_complete(corrutina_principal())
Creación y gestión de tareas asíncronas
Ejecución paralela de tareas
El código asíncrono muestra su verdadero poder al ejecutar varias tareas en paralelo:
async def tarea(nombre, retraso):
print(f"Tarea {nombre} iniciada")
await asyncio.sleep(retraso)
print(f"Tarea {nombre} completada después de {retraso} segundos")
return f"Resultado de {nombre}"
async def main():
# Forma 1: asyncio.gather()
resultados = await asyncio.gather(
tarea("A", 2),
tarea("B", 1),
tarea("C", 3)
)
print("Todos los resultados:", resultados)
asyncio.run(main())
Crear tareas con asyncio.create_task()
Para tener más control sobre la ejecución, usa asyncio.create_task():
async def main():
# Creamos las tareas
tarea_a = asyncio.create_task(tarea("A", 2))
tarea_b = asyncio.create_task(tarea("B", 1))
tarea_c = asyncio.create_task(tarea("C", 3))
# Esperamos a que terminen
await tarea_a
await tarea_b
await tarea_c
asyncio.run(main())