Rust 中的 await
Nilesh Katuwal
2022年7月18日
在本文中,我们将学习 Rust 中 await
的含义。
Rust 中的 await
async-await
是一种编写函数的技术,可以暂停、将控制权交给运行时,然后从中断的地方继续执行。通常,这些暂停用于等待 I/O,但它们可以用于各种目的。
async-await
可能对 JavaScript 或 C# 很熟悉。然而,Rust 的功能实现有一些重要的变化。
要使用 async-await
,你必须将 fn
替换为 async fn
:
async fn new_fxn() -> u32 { .. }
与传统函数相比,调用 async fn
不会立即生效。相反,它返回一个 future
。
计算暂停并等待执行。使用 .await
运算符执行 future
:
async fn second_fxn () {
let future = new_fxn();
let result: u32 = future.await;
...
}
这个例子说明了 Rust 和其他语言的第一个区别:我们写 future.await
而不是 await future。这种语法与 Rust 的 ?
更好地交互。用于传播错误的运算符,这在 I/O 中很常见。
你可以写 future.await?
承担过错,等待很多的结果。此外,它还具有使链接方法无痛的好处。
await
一词只能在异步函数的上下文中使用,并且只能等待异步函数。
Rust 的 futures
是宽松的;默认情况下,在进行第一次轮询之前,它们将不做。当你等待
这个未来
时,它就会被调查。
例如,如果你调用一个函数,该函数在程序开始时返回 future
,但直到程序结束才等待
它,则在你等待
它之前不会执行实际请求。
例子:
use std::thread;
use tokio::time::{sleep, Duration};
use futures::future;
#[tokio::main]
async fn main(){
let mut await_demo = Vec::new();
for count in 1..=5
{
await_demo.push(tokio::spawn(async move{
println!("Start the thread {count}, id= {:?}", thread::current().id());
sleep (Duration::from_millis(5000)).await;
println!("end the thread {count}, id = {:?})", thread::current().id());
}));
}
future::join_all (await_demo).await;
}
首先,创建五个 futures
(五个 async
块),每个 future
创建一个 sleep
future 并在其上调用 await
。这些未来
同时存在。
每个块显示 await
之前和之后的线程 ID。
输出:
Standard Output
Start the thread 1, id= ThreadId(2)
Start the thread 3, id= ThreadId(2)
Start the thread 4, id= ThreadId(2)
Start the thread 5, id= ThreadId(2)
Start the thread 2, id= ThreadId(3)
end the thread 2, id = ThreadId(2))
end the thread 3, id = ThreadId(3))
end the thread 1, id = ThreadId(3))
end the thread 4, id = ThreadId(3))
end the thread 5, id = ThreadId(3))