尽管第一次发行稳定的"async-await"是一个重大事件,但这也仅仅是开始。当前对async-await的支持是一种“最小可行产品”(MVP)。我们预计将在一段时间内对其进行打磨、改进和扩展。
自async-await进入测试版本以来,我们已经取得了很大的进步,包括进行了一些重要的诊断改进,这些改进有助于使async-await的错误更易理解。要参与这项工作,请查看Async Foundations Working Group;您也可以帮助我们归类整理问题或提名最需要解决的问题来指导我们的工作。
非常感谢使async-await得以实现的人们。这些设计和实现离不开cramertj和withoutboats的领导、编译器方面的实现和完善工作(davidtwco,tmandry,gilescope,csmoe)、核心生成器的支持(Zoxc)、Future
和Pin
API的基础工作(aturon,alexcrichton,RalfJ,pythonesque),当然还有许多社区成员在RFC和讨论中提供的信息。
现在,async-await接近稳定,所有主要的异步I/O运行时都在添加和扩展对新语法的支持:
(本节和之后的部分摘自_“Async-await hits beta!” _一文。)
那么,异步等待是什么?异步等待是一种编写函数(function)的方法,可以“暂停”函数,将控制权返回给运行时,随后可以从中断处重新开始。通常,这些暂停是为了等待I/O,但也有多种其它的用途。
您可能熟悉JavaScript或C#中的async-await。Rust版本的与其功能相似,但有一些主要区别。
要使用async-await,首先要编写async fn而不是fn:
async fn first_function()-> u32 { .. }
与常规函数不同,调用async fn
不会立即生效。而是返回一个Future
。这是一个等待执行的暂缓操作。要实际执行future, 使用.await操作符:
async fn another_function() {
// Create the future:
let future = first_function();
// Await the future, which will execute it (and suspend
// this function if we encounter a need to wait for I/O):
let result: u32 = future.await;
...
}
这个例子显示了Rust与其他语言之间的第一个区别:我们编写的是future.await
而不是await future
。该语法与Rust中传播错误的?
操作符集成得更好(在I/O中非常常见)。您可以简单地写future.await?
等待future的结果并传播错误。它还具有使方法链接变得更顺畅的优势。
Rust的future与JS和C#中的future之间的另一个区别是,它基于“poll”模型,这使它是零开销的。在其他语言中,调用异步函数会立即创建一个future,并安排其执行时间:执行future不需要等待future。但这意味着创建的每个将来都会有一些开销。
相反,在Rust中,调用异步函数本身并不会进行任何调度,这意味着我们可以组成一个复杂的future嵌套,而不会产生单个future的开销。作为最终用户,你会发现future是惰性的:在你await它之前,它什么都不做。
如果您想进一步了解future的幕后运作方式,请查看async book的executor部分,或观看withoutboats在Rust LATAM 2019上就该主题进行的精彩演讲。
我们相信,async-await进入Rust稳定版将成为Rust中许多新的令人振奋的开发的关键推动力。 如果您过去在Rust中尝试过异步I/O并遇到了问题-特别是如果你尝试了过去基于combinator的future,你会发现async-await与Rust的借用系统集成得更好。 此外,现在生态系统中有许多出色的运行时库和其他库可供使用。行动起来,构建一些东西吧!
原文:https://blog.rust-lang.org/2019/11/07/Async-await-stable.html