Master

Async Rust

Write asynchronous code with async/await and futures.

What you will see

1 2

About 2 min of reading

Try It

You will write asynchronous code with async/await, run it on the Tokio runtime, and use join to run concurrently.

1

I define an async function that returns a string and await it. The tokio runtime drives the future to completion.

async fn fetch() -> String { "data".to_string() } #[tokio::main] async fn main() { let result = fetch().await; println!("{}", result); }

Before you run it, say out loud what it will print. Then open the answer.

What it prints
data
2

I join two futures so they run concurrently. tokio::join! waits for both to finish.

async fn first() -> String { "one".to_string() } async fn second() -> String { "two".to_string() } #[tokio::main] async fn main() { let (a, b) = tokio::join!(first(), second()); println!("{} {}", a, b); }

Before you run it, say out loud what it will print. Then open the answer.

What it prints
one two
3

I sleep inside an async block. The await yields control while the runtime waits for the delay to elapse.

#[tokio::main] async fn main() { tokio::time::sleep(std::time::Duration::from_millis(50)).await; println!("after delay"); }

Before you run it, say out loud what it will print. Then open the answer.

What it prints
after delay
4

I await a future without a runtime. The compiler rejects the await, showing async code needs a runtime like tokio.

async fn run() { let _ = async {}; } fn main() { run(); }

Before you run it, say out loud what it will print. Then open the answer.

What it prints
BUILDS_OK
5

I define two async blocks and await them in order. Each completes before the next starts.

#[tokio::main] async fn main() { let a = async { 1 }; let b = async { 2 }; let x = a.await; let y = b.await; println!("{} {}", x, y); }

Before you run it, say out loud what it will print. Then open the answer.

What it prints
1 2

Put it in order

Before you write anything, put these lines back in the right order. Click a line to move it up one step. This support step is easier than writing code from scratch, and it is here to make the last example stick.

Data Flow

A future pauses at await and yields; the runtime drives it forward.
1 Create a future with async
↓
2 Await it to yield control
↓
3 Runtime runs other work
↓
4 Future completes when awaited
Why this works
Async runtime

Async code needs a runtime to drive futures:

#[tokio::main]
async fn main() {
    // runs on the Tokio runtime
}

tokio is the most popular runtime. It provides the event loop, timers, and IO. Other runtimes include async-std and async-tokio.

Why it works: the runtime multiplexes many futures onto few threads.

When you have a choice

Blocking vs async

Not everything is async:

async fn run() {
    let slow = blocking_work();  // blocks the thread!
    slow.await;                  // wrong, should be async
}

Mixing blocking calls into async code stalls the runtime. Use blocking IO libraries or offload to a thread pool for heavy work.

Examples

async fn

Async functions

async fn fetch() -> String {
    "data".to_string()
}

#[tokio::main]
async fn main() {
    let result = fetch().await;
    println!("{}", result);
}

async fn defines a function that can pause. .await waits for its result. Async code needs a runtime like Tokio.

Why it works: await lets one task do other work while waiting.

Futures

The future type

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

async fn delayed() {
    sleep(Duration::from_secs(1)).await;
}

A future is a value that produces a result later. async blocks create futures. They only run when awaited on a runtime.

Why it works: futures are zero-cost abstractions over polling.

Joining futures

Running concurrently

#[tokio::main]
async fn main() {
    let (a, b) = tokio::join!(
        first(),
        second()
    );
    println!("{a} {b}");
}

tokio::join! runs multiple futures concurrently and waits for both. Without it, each future would run to completion in sequence.

Why it works: join interleaves the futures' work.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Concurrency
Previous Lesson
Concurrency