try_join 多个不同类型的 Futures 向量

问题描述 投票:0回答:1

我们有有限数量的 vec(长度未知)的期货。每个 future vec 都有不同的结果类型,因此我们不能只是将它们展平。我们想做一些类似 try_join 的事情,等待一个返回错误,或者全部返回成功。

执行此连接的位置已经在异步上下文中。加入的 future 必须同时处于活动状态,因此我们不能一次尝试加入一个 vec。

在 Rust 异步中实现这个的好方法是什么?

rust async-await rust-tokio
1个回答
0
投票

您可以添加一个中间映射步骤,将每个

Future
的结果转换为一致的类型,然后再将它们传递给
try_join_all

use futures::future::FutureExt;
use std::future::Future;
use std::pin::Pin;

#[tokio::main]
async fn main() {
    let int_futures: Vec<Pin<Box<dyn Future<Output = Result<String, u8>> + Send>>> = vec![
        async { Ok("ok".to_owned()) }.boxed(),
        async { Err(0) }.boxed(),
    ];

    let bool_futures: Vec<Pin<Box<dyn Future<Output = Result<String, bool>> + Send>>> = vec![
        async { Ok("ok".to_owned()) }.boxed(),
        async { Err(false) }.boxed(),
    ];

    #[derive(Debug)]
    #[allow(unused)]
    enum EitherError {
        Int(u8),
        Bool(bool),
    }

    let result: Result<Vec<String>, EitherError> = futures_util::future::try_join_all(
        int_futures
            .into_iter()
            .map(|f| -> Pin<Box<dyn Future<Output = _>>> {
                f.map(|r| r.map_err(EitherError::Int)).boxed()
            })
            .chain(
                bool_futures
                    .into_iter()
                    .map(|f| -> Pin<Box<dyn Future<Output = _>>> {
                        f.map(|r| r.map_err(EitherError::Bool)).boxed()
                    }),
            ),
    )
    .await;

    // e.g. Err(Int(0))
    println!("{result:?}");
}
© www.soinside.com 2019 - 2024. All rights reserved.