New to Rust. I want to wait for the following async tasks to finish:
let _ = tokio::try_join!(fetch_handle, evaluate_handles[0], evaluate_handles[1], evaluate_handles[2], evaluate_handles[3]);
Is there a way to do this without hard-coding each item in evaluate_handles
? evaluate_handles
is a Vec<JoinHandle<()>>
, and fetch_handle
is just a single JoinHandle<()>
In general, you can use TryJoinAll
to do try_join!
on an iterator of tasks (futures):
use futures::future::TryJoinAll;
let join_evaluate_handles = evaluate_handles.into_iter().collect::<TryJoinAll<_>>();
In your case, all the join handles have the same type, so you could just construct an iterator that contains them all:
evaluate_handles.into_iter()
.chain(once(fetch_handle))
.collect::<TryJoinAll<_>>()
.await
If they weren't the same type, you would combine TryJoinAll
and try_join!
:
try_join!(fetch_handle, join_evaluate_handles /* from above */)
Note, however, that I'm not sure it's super meaningful to use try_join
here anyway. try_join
's main point is that it returns immediately if one of the futures errors. But your futures are JoinHandle
s, and those only error when the spawned task panics: Playground
Now, panicking in a spawned future makes tokio print an ugly error message, and you want to avoid that in general. The only practical use-case for using try_join
here I can think of is aborting your application if a panic happens somewhere. But I think there's less hassle-full ways of doing this.
One more note: If you're using TryJoinAll
or FuturesUnordered
, there's no real need to tokio::spawn
your tasks in the first place.