1.4. async/await! 入门

未匹配的标注

async/.await 入门

async/.await 是 Rust 语言用于编写像同步代码一样的异步函数的内置工具。async 将一个代码块转化为一个实现了名为Future的特质(trait)的状态机。虽然在同步方法中调用阻塞函数会阻塞整个线程,但阻塞的Futures将让出线程控制权,允许其他Futures运行。

要创建异步函数,可以使用async fn语法:

async fn do_something() { ... }

async fn返回的值是一个Future,需要在执行者上运行才能起作用:

// `block_on` blocks the current thread until the provided future has run to
// completion. Other executors provide more complex behavior, like scheudling
// multiple futures onto the same thread.
use futures::executor::block_on;

async fn hello_world() {
    println!("hello, world!");
}

fn main() {
    let future = hello_world(); // Nothing is printed
    block_on(future); // `future` is run and "hello, world!" is printed
}

async fn中,你可以使用.await 等待另一种实现Future特性的类型完成,例如另一个async fn的输出。 与block_on不同,.await 不会阻止当前线程,而是异步等待Future完成,如果Future无法取得进展,则允许其他任务运行。

例如,假设我们有三个async fnlearn_songsing_songdance

async fn learn_song() -> Song { ... }
async fn sing_song(song: Song) { ... }
async fn dance() { ... }

一种执行“学习”、“唱歌” 和 “跳舞” 的方法是,在执行每一项任务时阻塞:

fn main() {
  let song = block_on(learn_song());
  block_on(sing_song(song));
  block_on(dance);
}

但是,我们使用这种方式并没有发挥出最大的性能——我们只是把它们一个个执行了。很明显,我们唱歌之前必须要学会它,但是在学歌和唱歌的同时我们也是可以跳舞的。要实现这样的效果,我们可以分别创建两个 async fn 来并发地执行:

async fn learn_and_sing() {
    // 在唱歌之前等待学歌完成
    // 这里我们使用 `.await` 而不是 `block_on` 来防止阻塞线程,这样就可以同时执行 `dance` 了。
    let song = learn_song().await;
    sing_song(song).await;
}
 async fn async_main() {
    let f1 = learn_and_sing();
    let f2 = dance();
     // `join!` 类似于 `.await` ,但是可以等待多个 future 并发完成
     // 如果学歌的时候有了短暂的阻塞,跳舞将会接管当前的线程,如果跳舞变成了阻塞
     // 学歌将会返回来接管线程。如果两个futures都是阻塞的,
     // 这个‘async_main'函数就会变成阻塞状态,并生成一个执行器
    futures::join!(f1, f2)
}
 fn main() {
    block_on(async_main());
}

在本例中,学歌必须发生在唱歌之前,但是学习和唱歌当同时都可以跳舞。如果我们在 learn_and_sing中使用block_on(learn_song())而不是 learn_song().await 的话,它的执行将阻塞至学歌结束,就无法同时跳舞了。通过 .await 学歌这一操作,我们允许其他任务并发执行。

到目前为止你已经学会了 async/.await的基本用法,现在我们尝试写一个例子。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
贡献者:1
讨论数量: 1
发起讨论 只看当前版本


Dollarkillerx
根据上面的代码 这里貌似还是同步的
0 个点赞 | 1 个回复 | 分享 | 课程版本 2018