是否可以在不消耗其输出的情况下检查未来是否已准备好?

mal*_*tor 6 asynchronous rust rust-tokio

Rust 中的 Future 可以在不阻塞的情况下进行轮询,以检查 future 是否准备好(并在此过程中做一些工作)。考虑到这一点,是否可以在不消耗其输出的情况下“检查”未来是否已准备好?

可能的情况

stdin如果有任何数据,将会被轮询,并对输入(playground)采取行动:

async fn read_input_if_available() {
    use tokio::io::AsyncReadExt;

    let mut stdin = tokio::io::stdin();

    // if !stdin.ready() {
    //    return;
    // }

    let mut input = String::new();
    let mut buffer = [0_u8; 1024];

    while let Ok(bytes) = stdin.read(&mut buffer).await {
        if let Ok(string) = std::str::from_utf8(&buffer[..bytes]) {
            input.push_str(string);
        }
    }

    // Take action on `input` here
}
Run Code Online (Sandbox Code Playgroud)

当代码命中 时await,直到标准输入上有内容为止,即使只是等待EOF.

我使用tokio::io::Stdin它是因为它对于一个独立的示例来说更简单,但问题是关于 Rust 期货的。

She*_*ter 7

不,不是直接。与迭代器一样,Future 和 Stream 是一次性的:您只能获得pollor的结果poll_next一次。

迭代器有peekable方法,futures 和流有类似的:

在某些情况下,您可以结合使用可变引用FutureExt::now_or_never的实现:Future

use futures::FutureExt; // 0.3.13
use std::time::Duration;
use tokio::time; // 1.3.0

#[tokio::main]
async fn main() {
    let mut f = something_else().boxed();

    if let Some(v) = (&mut f).now_or_never() {
        eprintln!("it was ready and it was {}", v);
    } else {
        time::sleep(Duration::from_millis(500)).await;

        let v = f.await;
        eprintln!("now it's ready and it was {}", v);
    }
}

async fn something_else() -> i32 {
    //time::sleep(Duration::from_millis(1000)).await;
    42
}
Run Code Online (Sandbox Code Playgroud)

您确实需要确保未来实现Unpin(通过此处完成FutureExt::boxed,并且在它已经完成后您不能再执行.await未来。