如何在Rust中解析Future?求JS异步示例转Rust的简单实现
将JavaScript异步Promise转换为Rust Future的简洁示例
在Rust里,你完全不需要手动实现Future trait来创建简单的异步任务——主流异步运行时(比如tokio)已经提供了开箱即用的工具,和JS里的Promise使用逻辑非常接近。
最简洁的实现(推荐)
先在Cargo.toml中添加tokio依赖:
[dependencies] tokio = { version = "1.0", features = ["full"] }
然后编写对应代码:
use tokio::time::{sleep, Duration}; // async关键字标记的函数会自动返回一个实现了Future trait的类型 async fn some_async_task() -> &'static str { // 用sleep模拟1秒延迟,对应JS的setTimeout sleep(Duration::from_secs(1)).await; "result" } // tokio的main宏用来启动异步运行时 #[tokio::main] async fn main() { // await获取异步任务的结果,对应JS的await let result = some_async_task().await; println!("{}", result); }
手动实现Future(仅用于理解原理)
如果想了解Future trait的底层逻辑,这里给一个极简的手动实现示例(实际开发完全没必要这么做):
use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; // 自定义结构体作为Future的载体 struct SimpleAsyncTask { is_completed: bool, } impl Future for SimpleAsyncTask { // 定义Future完成后返回的类型,对应Promise的resolve值类型 type Output = &'static str; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { if self.is_completed { // 任务已完成,返回结果 Poll::Ready("result") } else { // 标记任务完成(实际场景中这里会触发真正的异步操作,比如定时器回调) self.get_mut().is_completed = true; // 通知调度器:这个Future已经准备好再次被检查了 cx.waker().wake_by_ref(); // 告诉调度器当前任务还未完成,稍后再试 Poll::Pending } } } async fn some_async_task() -> &'static str { SimpleAsyncTask { is_completed: false }.await } #[tokio::main] async fn main() { let result = some_async_task().await; println!("{}", result); }
关键逻辑说明
Futuretrait的核心是poll方法:返回Poll::Pending表示任务未完成,需要调度器后续重新检查;返回Poll::Ready(T)表示任务完成并返回结果。cx.waker()用来获取唤醒器,当异步操作完成时(比如定时器到点),调用它可以通知调度器再次poll这个Future。- 实际开发中,
async fn会被编译器自动转换成实现Future的匿名类型,不需要手动编写结构体和实现trait。
内容的提问来源于stack exchange,提问作者Levap
相关产品推荐
相关产品推荐

