You could use select! for this:
use tokio::time::{sleep, Duration};
use tokio::{pin, select};
#[tokio::main]
async fn main() {
let main_task = async {
println!("foo");
};
pin!(main_task);
let background_task = async {
sleep(Duration::from_millis(1_000)).await;
println!("qux");
};
pin!(background_task);
let mut main_task_complete = false;
let mut background_task_complete = false;
while !main_task_complete || !background_task_complete {
select! {
_ = &mut main_task, if !main_task_complete => {
main_task_complete = true;
}
_ = &mut background_task, if !background_task_complete => {
background_task_complete = true;
}
}
}
}
Or FuturesUnordered:
use tokio::time::{sleep, Duration};
use std::future::Future;
use std::pin::Pin;
use futures::stream::{FuturesUnordered, StreamExt};
#[tokio::main]
async fn main() {
let main_task = async {
println!("foo");
};
let main_task: Pin<Box<dyn Future<Output = ()>>> = Box::pin(main_task);
let background_task = async {
sleep(Duration::from_millis(1_000)).await;
println!("qux");
};
let background_task: Pin<Box<dyn Future<Output = ()>>> = Box::pin(background_task);
let futures = FuturesUnordered::from_iter([main_task, background_task]);
futures.collect::<()>().await;
}