Rust
await
Wait for a future with .await.
await
.await waits for a future to complete and gives its result. It can only be used in an async context. While waiting, the thread isn't blocked: the runtime can run other tasks on the same thread:
async fn fiyat(id: u32) -> u32 {
id * 10 // in reality: a database query
}
async fn toplam() -> u32 {
let a = fiyat(1).await;
let b = fiyat(2).await;
a + b
}
Here the two calls run sequentially. Running them concurrently needs tools like join!.
await is a suspension point
The compiler turns an async function into a state machine; each .await is a state. If the future isn't ready yet, the function pauses at that point and its local variables are kept inside the state machine. That's why, in async functions, the future itself carries the variables instead of the stack.
// conceptually:
enum Toplam {
Basla,
BirinciBekliyor { f: FiyatFuture },
IkinciBekliyor { a: u32, f: FiyatFuture },
Bitti,
}
Exercise Chained await
Write the async functions fiyat and toplam above. Print the result of toplam() with block_on.
Show example solution
use std::future::Future;
use std::pin::pin;
use std::task::{Context, Poll, Waker};
fn block_on<F: Future>(f: F) -> F::Output {
let mut f = pin!(f);
let mut cx = Context::from_waker(Waker::noop());
loop {
if let Poll::Ready(v) = f.as_mut().poll(&mut cx) {
return v;
}
}
}
async fn fiyat(id: u32) -> u32 {
id * 10
}
async fn toplam() -> u32 {
let a = fiyat(1).await;
let b = fiyat(2).await;
a + b
}
fn main() {
println!("{}", block_on(toplam()));
}
Test yourself
-
What happens if <code>.await</code> is written in a normal (non-async) function?
- E0728: await only inside async functions and blocks
- It works
- The thread blocks
- It warns
Show answer
E0728: await only inside async functions and blocks — To run a future from synchronous code, an executor entry point like block_on is used.
-
Wait for the result
async fn toplam() -> u32 {
let a = fiyat(1).____;
a
}
Show answer
async fn toplam() -> u32 {
let a = fiyat(1).await;
a
}
-
Expression and type
- fiyat(1)
- impl Future<Output = u32>
- fiyat(1).await
- u32
- toplam()
- A future not yet run
- block_on(toplam())
- 30
Next lesson: Future trait