Async/Await

为什么在 39 节介绍了闭包相关内容?因为在大多数情况下,无论是使用 futures 还是 async/await 实现 std::future::Future trait 都只是另一个包装闭包的结构!

下面写 2 个普通函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

fn do3() {
for i in 1..=5 {
println!("do3 {}", i);
sleep(Duration::from_millis(500));
}
}

fn do4() {
for i in 1..=5 {
println!("do4 {}", i);
sleep(Duration::from_millis(1000));
}
}

fn main() {
do3();
do4();
}

以上代码会顺序执行,先执行 do3(),然后执行 do4()。

我们想要提高效率,代码修改如下:

1
2
3
4
5
6
7
fn main() {
let do3_spawn = spawn(do3);
let do4_spawn = spawn(do4);

do3_spawn.join().unwrap();
do4_spawn.join().unwrap();
}

下面使用 async/await 改造代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
use async_std::task::{sleep, spawn};
use std::time::Duration;

async fn do3() {
for i in 1..=5 {
println!("do3 {}", i);
sleep(Duration::from_millis(500)).await;
}
}

async fn do4() {
for i in 1..=5 {
println!("do4 {}", i);
sleep(Duration::from_millis(1000)).await;
}
}

#[async_std::main]
async fn main() {
let do3_async = spawn(do3());
do4().await;
do3_async.await;
}
  • 使用 async_std::task。
  • 在 do3 和 do4 函数前都加 async。
  • 在主函数上使用#[async_std::main]属性。
  • 主函数前也有 async 关键字。
  • 在调用 sleep 之后添加.await。注意不是.await()调用,而是一个新语法。
  • 使用 spawn(do3())而不是 spawn(do3),这表示直接调用 do3 并将结果传给 spawn。
  • 对 do4()的调用增加.await。
  • 对 sleepus 不再使用 join(),而是改用.await 语法。

async 关键字的作用

  1. 可以在函数体内使用.await 语法。
  2. 它修改了函数的返回类型。
    async fn 函数名称() -> 返回值类型 实际上返回的是 impl std::future::Future<Output=返回值类型>
  3. 自动将结果值封装进一个新的 Future 对象。

下面看一下拆解 async

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
use futures::executor::block_on;
use std::future::Future;

async fn lesson() -> String { String::from("从0到Go语言微服务架构师") }

fn study1() -> impl Future<Output = String> {
async {
let x = lesson().await;
x+" 学习目标"
}
}

fn go_study() -> impl Future<Output = String> {
let r = |x: String| async move {
let y:String = study1().await;
y + &*x
};
r(String::from(":全面掌握Go语言微服务落地,代码级一次性解决微服务和分布式系统。"))
}
fn main() {
let result = block_on(go_study());
println!("{}", result);
}

//输出
从0到Go语言微服务架构师 学习目标:全面掌握Go语言微服务落地,代码级一次性解决微服务和分布式系统。

添加微信 公众号更多内容
wechat gzh