Async Concepts
Async Block
Build a Future Inline
An async block creates a future from a block of code. Values captured from the surrounding scope can be awaited inside it.
Program
Play the program to choose a bonus value and compute a total inside an async block.
async_block.rs
use std::future::Future;
use std::pin::pin;
use std::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
fn main() {
let bonus = ;
let future = async {
let left = ready_value(10).await;
let right = ready_value(bonus).await;
left + right
};
let total = block_on(future);
println!("{total}");
}
async fn ready_value(value: i32) -> i32 {
value
}
fn block_on<F: Future>(future: F) -> F::Output {
let waker = noop_waker();
let mut context = Context::from_waker(&waker);
let mut future = pin!(future);
loop {
match future.as_mut().poll(&mut context) {
Poll::Ready(value) => return value,
Poll::Pending => {}
}
}
}
fn noop_waker() -> Waker {
unsafe { Waker::from_raw(noop_raw_waker()) }
}
fn noop_raw_waker() -> RawWaker {
RawWaker::new(std::ptr::null(), &VTABLE)
}
static VTABLE: RawWakerVTable = RawWakerVTable::new(|_| noop_raw_waker(), |_| {}, |_| {}, |_| {});
use std::future::Future;
use std::pin::pin;
use std::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
fn main() {
let bonus = ;
let future = async {
let left = ready_value(10).await;
let right = ready_value(bonus).await;
left + right
};
let total = block_on(future);
println!("{total}");
}
async fn ready_value(value: i32) -> i32 {
value
}
fn block_on<F: Future>(future: F) -> F::Output {
let waker = noop_waker();
let mut context = Context::from_waker(&waker);
let mut future = pin!(future);
loop {
match future.as_mut().poll(&mut context) {
Poll::Ready(value) => return value,
Poll::Pending => {}
}
}
}
fn noop_waker() -> Waker {
unsafe { Waker::from_raw(noop_raw_waker()) }
}
fn noop_raw_waker() -> RawWaker {
RawWaker::new(std::ptr::null(), &VTABLE)
}
static VTABLE: RawWakerVTable = RawWakerVTable::new(|_| noop_raw_waker(), |_| {}, |_| {}, |_| {});
use std::future::Future;
use std::pin::pin;
use std::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
fn main() {
let bonus = ;
let future = async {
let left = ready_value(10).await;
let right = ready_value(bonus).await;
left + right
};
let total = block_on(future);
println!("{total}");
}
async fn ready_value(value: i32) -> i32 {
value
}
fn block_on<F: Future>(future: F) -> F::Output {
let waker = noop_waker();
let mut context = Context::from_waker(&waker);
let mut future = pin!(future);
loop {
match future.as_mut().poll(&mut context) {
Poll::Ready(value) => return value,
Poll::Pending => {}
}
}
}
fn noop_waker() -> Waker {
unsafe { Waker::from_raw(noop_raw_waker()) }
}
fn noop_raw_waker() -> RawWaker {
RawWaker::new(std::ptr::null(), &VTABLE)
}
static VTABLE: RawWakerVTable = RawWakerVTable::new(|_| noop_raw_waker(), |_| {}, |_| {}, |_| {});
async block
`async { ... }` builds a future without naming a separate async function.
capture
The async block can read `bonus` from the surrounding scope.
await sequence
Each `.await` returns a value before the next expression uses it.