Rust async/await

async/await 与 Future 模型:异步函数返回 Future,需执行器驱动;.await 点协作式让出。

#type / concept #status / growing #tech / dev #resource / rust

[!info] 关联笔记

Rust async/await

这个概念为什么出现

高并发 I/O 若一连接一线程成本高。
Rust 的 async/await 提供零成本风格的异步语法:async fn 变成实现 Future 的状态机,由运行时轮询。

[!abstract] 一句话理解 async fn 返回 impl Future.await 在 Future 未就绪时让出执行;没有执行器,Future 不会自己跑起来。

最小可运行示例

场景:可组合的异步“假 I/O”——顺序等待两个步骤

无引入第三方运行时的情况下,用标准库手动 poll 不现实写长文;此处用语法形态 + 同步对照说明概念,并在注释中标明生产用 Tokio。

// 业务意图:表达“先校验、再计费”两步异步流程的代码形状。
// 教学点:async fn 返回 Future;需要执行器才能运行。
// 注意:本示例在 stable 上若无执行器,仅展示函数形态,不直接在 main await。

async fn validate_order(id: u64) -> Result<(), String> {
    if id == 0 {
        return Err("bad id".into());
    }
    Ok(())
}

async fn charge(id: u64) -> Result<u32, String> {
    let _ = validate_order(id).await?;
    Ok(100) // 金额分
}

// 生产环境:
// #[tokio::main]
// async fn main() { charge(1).await.unwrap(); }
fn main() {
    println!("async functions compile to futures; run them with an executor (e.g. Tokio)");
    let _future = charge(1); // 创建 Future 但未驱动
}

建议运行:cargo run

期望输出:

async functions compile to futures; run them with an executor (e.g. Tokio)

结合场景再看三个关注点

  1. Future 惰性:创建 ≠ 执行
  2. .await 只在 async 上下文
  3. 错误用 Result + ? 同样适用

核心概念与准确模型

  • FuturepollPending/Ready
  • 执行器/反应器:调度与 I/O 事件
  • Pin:自引用状态机安全
  • 取消:通常 drop Future

async 是并发模型,不等于多线程并行;可与多线程运行时组合。

设计动机

  • 语言级 async 语法
  • 与所有权/借用兼容
  • 生态可插拔运行时(Tokio、async-std 等)

边界与误区

  • 在 async 中阻塞会卡住工作线程
  • 不要 std::thread::sleep 代替 tokio::time::sleep
  • async trait 历史演进(RPITIT/async fn in trait 等按版本)

[!warning] 常见误区:认为 async fn 会自动并行 顺序 .await 是串行;并行要用 join!/spawn。

工程实践

  1. I/O 密集服务用 async 运行时
  2. CPU 密集放到 spawn_blocking 或独立线程池
  3. 统一错误与超时
  4. 取消与优雅关闭一起设计

本节总结

  • Future + 执行器
  • await 协作式
  • 生态运行时承接工程细节

自测题

  1. 为什么 main 不能直接 .await
  2. Future 被 drop 意味着什么?
参考答案
  1. main 默认不是 async 上下文,且需要执行器。
  2. 取消/停止该异步计算(需库支持协作点)。

延伸阅读与资料来源

资料类型支撑内容
The Async Book官方社区书async 模型
std::future::Future标准库Future
Tokio tutorial生态实践
创建于 2026/7/15 更新于 2026/7/15