Programación asíncrona en Rust: guía completa con ejemplos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción a la programación asíncrona en Rust



La programación asíncrona es un paradigma que permite ejecutar operaciones de entrada/salida (solicitudes de red, lectura de archivos, trabajo con bases de datos) sin bloquear el hilo principal de ejecución. En Rust, la asincronía se implementa a través del sistema Future y las palabras clave async/await. A diferencia del multihilo, el código asíncrono funciona en un solo hilo, cambiando entre tareas durante la espera.



En esta guía analizaremos:

  • Fundamentos de async/await en Rust
  • Trabajo con la crate tokio — el runtime asíncrono más popular
  • Creación y combinación de Future
  • Ejemplos prácticos: cliente HTTP asíncrono y temporizadores


El artículo está dirigido a desarrolladores familiarizados con la sintaxis básica de Rust. Si recién comienzas, te recomendamos estudiar primero los fundamentos del lenguaje en PythonLib.



Fundamentos de async/await y Future en Rust



¿Qué es Future?



Future es un trait que representa una operación asíncrona que puede completarse en el futuro. En Rust, Future es perezoso: no hace nada hasta que se le consulta (poll). El runtime asíncrono (por ejemplo, Tokio) es el encargado de realizar la consulta.



Un ejemplo simple de función asíncrona:



use std::time::Duration;

async fn say_hello() { println!("¡Hola desde el mundo asíncrono!"); tokio::time::sleep(Duration::from_secs(1)).await; println!("Ha pasado 1 segundo");}

#[tokio::main]async fn main() { say_hello().await;}


La palabra clave async convierte la función en un Future. La llamada .await suspende la ejecución de la tarea actual hasta que se complete el Future, sin bloquear el hilo.



Ciclo de vida de una tarea asíncrona



Cuando llamas a .await, ocurre lo siguiente:

  1. El runtime consulta el Future (llama al método poll())
  2. Si el Future está listo — devuelve el resultado
  3. Si el Future está esperando (por ejemplo, una operación de red) — el runtime cambia a otra tarea
  4. Cuando el recurso está disponible, el runtime reanuda la tarea


Una característica importante de Rust: .await solo puede llamarse dentro de una función asíncrona o un bloque async {}. Intentar usarlo en un contexto síncrono provocará un error de compilación.



Trabajo práctico con Tokio



Instalación y configuración



Tokio es un runtime asíncrono para Rust que proporciona un planificador de tareas, temporizadores, sockets de red y mucho más. Para empezar, agrega a Cargo.toml:



[dependencies]tokio = { version = "1", features = ["full"] }


La bandera features = ["full"] incluye todas las funcionalidades de Tokio. Para producción, es mejor seleccionar solo las características necesarias.



Ejecución de múltiples tareas asíncronas



Una de las principales ventajas de la asincronía es la ejecución paralela de múltiples tareas. Usa tokio::spawn para ejecutar tareas en segundo plano:



use tokio::time::{sleep, Duration};

async fn task(name: &str, seconds: u64) { println!("Tarea {} iniciada", name); sleep(Duration::from_secs(seconds)).await; println!("Tarea {} completada en {} seg", name, seconds);}

#[tokio::main]async fn main() { let handle1 = tokio::spawn(task("A", 2)); let handle2 = tokio::spawn(task("B", 1));

// Esperamos la finalización de ambas tareas let _ = tokio::join!(handle1, handle2); println!("Todas las tareas completadas");}


La macro tokio::join! espera la finalización de todos los Future pasados. Si una tarea termina antes, la ejecución no se interrumpe — esperamos a las demás.



Manejo de errores en código asíncrono

Blogs

Book Recommendations