Await 表达式
语法
Await表达式 :
表达式.
await
await
表达式是语法结构,用于暂停由实现了 std::future::IntoFuture
的计算,直到给定的 future 准备好产生值。
await
表达式的语法是一个实现了 IntoFuture
trait 的表达式,称为 future 操作数 ,后跟 .
和 await
关键字。
await
表达式只能在 async 上下文 中使用,比如 async fn
或 async
块 。更具体来说,await
表达式具有以下效果。
- 通过在 future 操作数上调用
IntoFuture::into_future
创建 future。 - 将 future 求解为 future
tmp
; - 使用
Pin::new_unchecked
固定tmp
; - 然后通过调用
Future::poll
方法并传递当前的 任务上下文 来对这个固定的 future 进行轮询; - 如果对
poll
的调用返回Poll::Pending
,那么 future 返回Poll::Pending
,暂停它的状态,以便当包围的 async 上下文重新被轮询时,执行返回到步骤 3 ; - 否则对
poll
的调用必须返回Poll::Ready
,在这种情况下,Poll::Ready
变体中包含的值将被用作await
表达式本身的结果。
版本差异:
await
表达式只从 Rust 2018 开始可用。
任务上下文
任务上下文指的是在当前 async 上下文 被轮询时提供给它的 Context
。
因为 await
表达式只能在 async 上下文中合法使用,所以必须有一些任务上下文可用。
近似解糖
实际上,一个 await 表达式大致相当于以下非规范的解糖:
match operand.into_future() {
mut pinned => loop {
let mut pin = unsafe { Pin::new_unchecked(&mut pinned) };
match Pin::future::poll(Pin::borrow(&mut pin), &mut current_context) {
Poll::Ready(r) => break r,
Poll::Pending => yield Poll::Pending,
}
}
}
其中 yield
伪代码返回 Poll::Pending
,并在重新调用时从该点恢复执行。
变量 current_context
指的是从异步环境中获取的上下文。