我正试图在Rust异步等待(即将稳定)中同时(而不是按顺序)运行一个期货列表,直到其中任何一个解析为true
。
想象一下,有一个Vec<File>
,并且将来每个文件运行一个会产生bool
(可能是无序的)的情况。这将是一个简单的序列化实现。
async fn my_function(files: Vec<File>) -> bool {
// Run the future on each file, return early if we received true
for file in files {
if long_future(file).await {
return true;
}
}
false
}
async fn long_future(file: File) -> bool {
// Some long-running task here...
}
这可行,但是我想同时运行其中的一些期货以加快流程。我碰到了buffer_unordered()
(在Stream
上),但不知道如何实现。
据我了解,假设您提供了多线程池,则类似join
的东西也可以同时运行期货。但是我不知道如何在这里有效地使用它。
我尝试了类似的方法,但是无法使它起作用:
let any_true = futures::stream::iter(files)
.buffer_unordered(4) // Run up to 4 concurrently
.map(|file| long_future(file).await)
.filter(|stop| stop) // Only propagate true values
.next() // Return early on first true
.is_some();
此外,我正在寻找迭代器中使用的类似any
的东西,以替换if语句或filter().next().is_some()
的组合。
我将如何处理?
答案 0 :(得分:2)
我认为您应该能够使用select_ok
,就像Some Guy提到的那样。一个示例,其中我用一堆u32
替换了文件进行说明:
use futures::future::FutureExt;
async fn long_future(file: u32) -> bool {
true
}
async fn handle_file(file: u32) -> Result<(), ()> {
let should_stop = long_future(file).await;
// Would be better if there were something more descriptive here
if should_stop {
Ok(())
} else {
Err(())
}
}
async fn tims_answer(files: Vec<u32>) -> bool {
let waits = files.into_iter().map(|f| handle_file(f).boxed());
let any_true = futures::future::select_ok(waits).await.is_ok();
any_true
}