Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Await 表达式

Syntax
AwaitExpressionExpression . await

await 表达式是一种语法结构,用于挂起由 std::future::IntoFuture 实现提供的计算,直到给定的 future 准备好产生一个值。

await 表达式的语法是一个类型实现了 IntoFuture trait 的表达式(称为future 操作数),然后是 . 记号,再然后是 await 关键字。

Await 表达式仅在异步上下文(如 async fnasync 闭包async)中合法。

更具体地说,await 表达式具有以下效果。

  1. 通过在 future 操作数上调用 IntoFuture::into_future 来创建 future。
  2. 将该 future 求值为一个 future tmp
  3. 使用 Pin::new_unchecked 固定 tmp
  4. 然后通过调用 Future::poll 方法并将当前的任务上下文传入来对此固定的 future 进行轮询;
  5. 如果对 poll 的调用返回 Poll::Pending,则 future 返回 Poll::Pending,挂起其状态,以便当外围异步上下文被重新轮询时,执行回到第 3 步;
  6. 否则对 poll 的调用必定返回了 Poll::Ready,在这种情况下,包含在 Poll::Ready 变体中的值被用作 await 表达式本身的结果。

2018 Edition differences

Await 表达式仅从 Rust 2018 起可用。

任务上下文

任务上下文指的是当异步上下文本身被轮询时提供给当前异步上下文Context。因为 await 表达式仅在异步上下文中合法,所以必须有某个任务上下文可用。

近似脱糖

实际上,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 引用从异步环境中获取的上下文。