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 期货的。
不,不是直接。与迭代器一样,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未来。