'How to spawn a repeating task and await its first execution?
Re-building setInterval in JS:
pub async fn set_interval<T, F>(interval: Duration, do_something: T)
where
T: (Fn() -> F) + Send + Sync + 'static,
F: Future + Send,
{
let forever = task::spawn(async move {
let mut interval = time::interval(interval);
loop {
interval.tick().await;
do_something().await;
}
});
forever.await;
}
This works, but I want it to be .awaitable until the first execution ends.
I.e. Instead of doing:
do_something().await
set_interval(Duration::from_secs(1), do_something)
I want to:
set_interval(Duration::from_secs(1), do_something).await
Note that this is different behaviour from above in that it runs the do_something task immediately, but it's intended.
My solution:
pub async fn set_interval<T, F>(interval: Duration, do_something: T)
where
T: (Fn() -> F) + Send + Sync + 'static,
F: Future + Send,
{
do_something().await;
task::spawn(async move {
let forever = task::spawn(async move {
let mut interval = time::interval(interval);
loop {
interval.tick().await;
do_something().await;
}
});
forever.await;
});
}
This works, but I have some doubts
- Is it a waste of resources to
task::spawntwice here? Any way it can be done only once? - Is it a mistake to discard the outer
task::spawnas soon as the function ends? Will it keep getting run indefinitely, even though it's not tracked anymore, just fired and forgotten?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
