Await expressions
等待(await)表达式
commit: f8e76ee9368f498f7f044c719de68c7d95da9972
本章译文最后维护日期:2020-11-13
句法
AwaitExpression :
Expression.await
等待(await)表达式仅在异步上下文中才能使用,例如 异步函数(async fn) 或 异步(async)块。等待(await)表达式内部操作一个 future 。它的作用是挂起当前计算,直到给定的 future 准备好生成返回值。
更具体地说 <expr>.await表达式有以下效果。
- 计算
<expr>到一个 futuretmp中; - 使用
Pin::new_unchecked固定住(Pin)这个tmp; - 然后通过调用
Future::poll方法对这个固定住的 future 进行轮询,同事将当前任务上下文传递给它; - 如果轮询(
poll)调用返回Poll::Pending,那么这个 future 就也返回Poll::Pending,并相应地挂起它的状态,这样,当包围它的异步上下文被再次轮询时,执行流返回到步骤2; - 否则,轮询(
poll)调用必定返回了Poll::Ready,在这种情况下,Poll::Ready变体中包含的值将被当作这个await表达式本身的求值结果。
版本差异: 等待(await)表达式只能从 Rust 2018 版开始才可用
Task context
任务上下文
任务上下文是指在对异步上下文本身进行轮询时提供给当前异步上下文的上下文(Context)。因为等待(await)表达式只能在异步上下文中才能使用,所以此时必须有一些任务上下文可用。
Approximate desugaring
近似脱糖
实际上,一个 <expr>.await表达式大致相当于如下代码(此脱糖不规范):
match /* <expr> */ {
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 是指从异步环境中获取的上下文。