Reputation: 29
I know that an async
function will return a Future, and that calling .await
on that future will repeatedly call poll()
on it until it completes, but I don't understand the difference between that and a regular function.
Does it give any benefit to make a function async
if it already works without it?
I have two versions of code that do the same thing. Consider the "experiment" functions as main functions running with #[tokio::main]
.
One version calls a regular function to create code that can run asynchronously with tokio::spawn()
(playground link, though it seems to not show the output well):
pub async fn experiment1() {
spawn_task(1);
spawn_task(2);
loop {
println!("3");
tokio::time::sleep(Duration::from_secs(1)).await;
}
}
fn spawn_task(n: i32) {
tokio::spawn(async move {
loop {
println!("{n}");
tokio::time::sleep(Duration::from_secs(1)).await;
}
});
}
The output of this is below (3 numbers print out every second, this is 3 seconds worth of output). Each loops runs concurrently.
3
1
2
3
2
1
3
1
2
The other version uses async
and await
(playground link, though it seems to not show the output well):
pub async fn experiment3() {
spawn_task(1).await;
spawn_task(2).await;
loop {
println!("3");
tokio::time::sleep(Duration::from_secs(1)).await;
}
}
async fn spawn_task(n: i32) {
tokio::spawn(async move {
loop {
println!("{n}");
tokio::time::sleep(Duration::from_secs(1)).await;
}
});
}
The output of this is below (3 numbers print out every second, this is 3 seconds worth of output). Each loops also runs concurrently.
3
1
2
3
1
2
3
2
1
Upvotes: 0
Views: 429
Reputation: 27533
When you only run synchronous code like in your examples the only
difference is that you change the return type from plain T
to
impl Future<Output = T>
. You might want to use this to use otherwise
synchronous functions in places where an asynchronous function is
expected.
The real benefit comes in when you actually use asynchronous code inside of it:
fn fun() {
// this is not allowed because we're not inside an async block or function
tokio::time::sleep(Duration::from_secs(1)).await;
}
The above function is not allowed, to make it work we have to declare
it as an async
function:
async fn fun() {
// we can use await here
tokio::time::sleep(Duration::from_secs(1)).await;
}
Upvotes: 3