当无法使 main 函数异步时如何在 Rust 中使用 async/await

Nig*_*eXD 24 rust async-await

我有一个下载异步文件的函数:

async fn download_file() {
    fn main() {
        let resp = reqwest::blocking::get("https://sh.rustup.rs").expect("request failed");
        let body = resp.text().expect("body invalid");
        let mut out = File::create("rustup-init.sh").expect("failed to create file");
        io::copy(&mut body.as_bytes(), &mut out).expect("failed to copy content");
    }
}
Run Code Online (Sandbox Code Playgroud)

我想调用这个函数来下载文件,然后在需要时等待它。
但问题是,如果我这样做,我会得到一个错误:

fn main() {
    let download = download_file();
    // Do some work
    download.await; // `await` is only allowed inside `async` functions and blocks\nonly allowed inside `async` functions and blocks
    // Do some work
}
Run Code Online (Sandbox Code Playgroud)

所以我必须使 main 函数异步,但是当我这样做时,我收到另一个错误:

async fn main() { // `main` function is not allowed to be `async`\n`main` function is not allowed to be `async`"
    let download = download_file();
    // Do some work
    download.await;
    // Do some work
}
Run Code Online (Sandbox Code Playgroud)

那么我该如何使用 async 和 wait
感谢您的帮助

msr*_*rd0 26

最常用的运行时 tokio 提供了一个属性宏,以便您可以使 main 函数异步:

#[tokio::main]
async fn main() {
    let download = download_file().await;
}
Run Code Online (Sandbox Code Playgroud)

如果您还没有对 tokio 的依赖,请将以下内容添加到您的Cargo.toml

tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
Run Code Online (Sandbox Code Playgroud)

  • @JohnMiller,你不需要“完整”,只需运行时和宏功能就足够了 (5认同)

oka*_*56k 8

这里有一个既定的模式。

从同步块构建一个新的运行时,然后调用block_on()它:

let rt = tokio::runtime::Builder::new_current_thread()
        .enable_all()
        .build()
        .unwrap();

let res = rt.block_on(async { something_async(&args).await });
Run Code Online (Sandbox Code Playgroud)