Rust 中的 await

Nilesh Katuwal 2022年7月18日
Rust 中的 await

在本文中,我们将学习 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))