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(())
}