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))