How to make multiple threads on "async function" which return `Result` type?

I have tried many time and methods for this but still failed;
Shall I get some more details guides for this?

async fn zig_once(work_dir: &str, base_urs: i64) -> Result<(f64, [f64; 3], f64, [f64; 3]), Box<dyn Error>> {
    //
    // many codes here;
    //
    Ok((pr1, pre1, pr2, pre2))
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let refer_list = vec![1, 2, 3, 4, 5];
    let mut preds_list = vec![];
    for i in 0..refer_list.len() {
        let work_diri = format!("/root/data_{}", i);
        preds_list.push(zig_once(work_diri.as_str(), base_frequence_hours).await?);
    }
    dbg!(preds_list);

    Ok(())
}

If I want to spawn multiple tasks that each compute some output I want to collect in the right order, I like to use futures::future::join_all, or the futures::stream::FuturesOrdered stream for this. FuturesOrdered has a nicer api when it comes to dealing with Result types IMO, thanks to the TryStreamExt trait.

Here examples for both:

join_all:

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let base_frequence_hours = 0;
    let refer_list = vec![1, 2, 3, 4, 5];
    
    let futures = (0..refer_list.len()).map(|i| {
        let work_diri = format!("/root/data_{}", i);
        zig_once(work_diri, base_frequence_hours)
    })
    .collect::<Vec<_>>();
    
    let preds_list: Vec<Result<_, _>> = join_all(futures).await;
    let preds_list = preds_list.into_iter().collect::<Result<Vec<_>, _>>()?;
  
    dbg!(preds_list);

    Ok(())
}

Playground.

FuturesOrdered:

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let base_frequence_hours = 0;
    let refer_list = vec![1, 2, 3, 4, 5];
    
    let futures = FuturesOrdered::from_iter((0..refer_list.len()).map(|i| {
        let work_diri = format!("/root/data_{}", i);
        zig_once(work_diri, base_frequence_hours)
    }));
    
    let preds_list: Result<Vec<_>, _> = futures.try_collect().await;
    
    dbg!(preds_list?);

    Ok(())
}

Playground.

3 Likes

Hi @jofas

Your solution is perfect for my request.
Thanks a lot.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.