async/await 基础
你会学到什么
async fn返回一个Future,只有.await时才推进执行。- Future 是惰性的,需要一个运行时(如 tokio)来驱动。
- 用
#[tokio::main]把main变成异步入口。
最小示例
async fn fetch(id: u32) -> String {
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
format!("data-{id}")
}
#[tokio::main]
async fn main() {
println!("{}", fetch(1).await);
}
运行代码
cd examples
cargo run -p rt_32_async_await
cargo test -p rt_32_async_await
依赖在该示例的 Cargo.toml 里:
[dependencies]
tokio = { version = "1", features = ["rt-multi-thread", "macros", "time"] }
代码讲解
async fn 本身不执行任何代码,它返回一个待执行的 Future。.await 把控制权交还给运行时,运行时在等待期间可以去跑别的任务:
async fn fetch_both() -> String {
let first = fetch(1).await; // 等第一个完成
let second = fetch(2).await; // 再等第二个
format!("{first},{second}")
}
测试用 #[tokio::test] 替代 #[test],它会在一个临时运行时里跑异步测试。
常见错误
调用 async 函数却忘了 .await,什么都不会发生:
fetch(1); // ❌ 返回一个被丢弃的 Future,sleep 不会执行
加上 .await(或把它交给 spawn/join!)。
练习
- 写一个 async 函数,顺序请求 3 个 id 并拼接结果。
- 把
sleep时间作为参数,观察 await 的耗时。
小结
async/await 把异步代码写得像同步一样直观,但 Future 惰性、需要运行时驱动是关键心智模型。
下一步
顺序 await 没有发挥并发优势。下一章学习并发任务:join! 与 spawn。
完整示例代码
下面是 examples/32_async_await/ 的完整源码。无需 clone 仓库,直接在页面上阅读、复制、对照运行。
examples/32_async_await/src/main.rs
//! async/await 基础:用 tokio 运行异步函数。
use std::time::Duration;
/// async 函数返回一个 Future,`.await` 时才真正执行。
async fn fetch(id: u32) -> String {
// 模拟一次异步 IO。
tokio::time::sleep(Duration::from_millis(10)).await;
format!("data-{id}")
}
/// 顺序 await 两个异步操作。
async fn fetch_both() -> String {
let first = fetch(1).await;
let second = fetch(2).await;
format!("{first},{second}")
}
#[tokio::main]
async fn main() {
println!("{}", fetch_both().await);
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn fetches_one() {
assert_eq!(fetch(7).await, "data-7");
}
#[tokio::test]
async fn fetches_both() {
assert_eq!(fetch_both().await, "data-1,data-2");
}
} examples/32_async_await/Cargo.toml
[package]
name = "rt_32_async_await"
version.workspace = true
edition.workspace = true
publish.workspace = true
[dependencies]
tokio = { version = "1", features = ["rt-multi-thread", "macros", "time"] }