I'm learning async/await using this document .I have a doubt in below code .
since I have delay in learn_singing() (and i assume this is some kind of block state) ,I'm expecting dance() to be completed first before learn_singing().
But o/p of the this code is sequential (which is no expected!! and i feel which is same if i use block_on() instead of await() in learn_and_sing()).
Can anybody help me in understanding what exactly is the difference between await & block_on() . and what exactly is wrong with this code?
struct Song {}
async fn learn_singing() -> Song {
thread::sleep(Duration::from_millis(7000));
println!("learn_singing()");
return Song {};
}
async fn sing(s: Song) {
println!("sing()");
}
async fn dance() {
println!("dance()");
}
async fn learn_and_sing() {
let s = learn_singing().await;
sing(s).await;
}
async fn sing_and_dance() {
let f1 = learn_and_sing();
let f2 = dance();
futures::join!(f1, f2);
}
fn main() {
block_on(sing_and_dance());
}
o/p :
learn_singing()
sing()
dance()
I was experimenting with await() call and my goal here is to "block" in learn_singing() so that dance completes first. in that case using thread::sleep should be ok right?
Only answering the title of the question (since the rest of it is not very clear to me): await is the opposite of blocking. Awaiting means that the current task gives up control to the runtime, so it is not being run for some amount of time, and other tasks are allowed to make progress. Blocking on the other hand means that the task remains active and continues to assert control, i.e. it doesn't allow other tasks scheduled on the same thread to run, even if it isn't doing anything useful.
Regarding thread::sleep, please see this blog post. As for what .await and block_on do differently, well, block_on goes from the blocking context to an async context (it can't be called in async context!), whereas .await is just used inside async contexts.
Here you should be aware that calling a non-async function does not really transition back out of the async context. The only way to do that would be something like Tokio's spawn_blocking function.