await
- Rust course
- Advanced
- Lesson 2/81
- 4 min
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,
}Practice Chained await
Write the async functions fiyat and toplam above. Print the result of toplam() with block_on.
Starter code
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;
}
}
}
fn main() {
// buraya yaz
}Sample 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()));
}Expected output
30
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 What happens if <code>.await</code> is written in a normal (non-async) function?
- E0728: await only inside async functions and blocks Correct answer
- It works
- The thread blocks
- It warns
Explanation: To run a future from synchronous code, an executor entry point like block_on is used.
2 Wait for the result
async fn toplam() -> u32 {
let a = fiyat(1).____;
a
}
async fn toplam() -> u32 {
let a = fiyat(1).await;
a
}
Explanation: .await gives the future's result.
3 Expression and type
| Term | Meaning |
|---|---|
fiyat(1) |
impl Future<Output = u32> |
fiyat(1).await |
u32 |
toplam() |
A future not yet run |
block_on(toplam()) |
30 |