前言
在之前我们主要介绍了通过await和block_on执行Future,但是这两种方式实际上都是顺序执行的方式。
.await是在代码块中按顺序执行,会阻塞后面的代码,但是此时会让出线程;block_on会阻塞直到Future执行完成。
本节我们介绍join宏,可以同时执行多个Future。
join宏
join宏允许在同时执行多个不同的Future并等待它们完成。
示例
- 源码
//src/main.rs
use futures;
use tokio::runtime::Runtime;
async fn function1() {
tokio::time::delay_for(tokio::time::Duration::from_secs(1)).await; //等待一秒钟
println!("function1 ++++ ");
}
async fn function2() {
println!("function2 ++++ ");
}
async fn async_main() {
let f1 = function1();
let f2 = function2();
// 使用await则会顺序执行,使用join则会并发执行f1和f2
// f1.await;
// f2.await;
futures::join!(f1, f2);
}
fn main() {
let mut runtime = Runtime::new().unwrap();
runtime.block_on(async_main());
println!("Hello, world!");
}
- Cargo.toml配置
[dependencies]
futures = "0.3.5"
tokio = { version = "0.2", features = ["full"] }
结果分析
如果在async_main中使用的await执行,则执行结果如下:
function1 ++++
function2 ++++
Hello, world!
如果在async_main中使用join执行,则执行结果如下:
function2 ++++
function1 ++++
Hello, world!
try_join宏
try_join和join宏类似,唯一的区别就是,当执行发送错误时就马上返回。
示例
- 源码
//src/main.rs
use futures::try_join;
use tokio::runtime::Runtime;
use std::io::Result;
async fn function1() -> Result<()> {
tokio::time::delay_for(tokio::time::Duration::from_secs(10)).await;
println!("function1 ++++ ");
Ok(())
}
async fn function2() -> Result<()> {
println!("function2 ++++ ");
Ok(())
}
async fn async_main() {
let f1 = function1();
let f2 = function2();
// f1.await;
// f2.await;
if let Err(_) = try_join!(f1, f2) {
println!("Err!")
}
}
fn main() {
let mut runtime = Runtime::new().unwrap();
runtime.block_on(async_main());
println!("Hello, world!");
}
- Cargo.toml配置文件
[dependencies]
futures = "0.3.5"
tokio = { version = "0.2", features = ["full"] }
- 运行结果
function2 ++++
function1 ++++
Hello, world!