加入

联接操作会等待一组 Future 全部就绪,然后返回它们的结果集合。这类似于 JavaScript 中的 Promise.al 或 Python 中的 asyncio.gather

  1. use anyhow::Result;
  2. use futures::future;
  3. use reqwest;
  4. use std::collections::HashMap;
  5. async fn size_of_page(url: &str) -> Result<usize> {
  6. let resp = reqwest::get(url).await?;
  7. Ok(resp.text().await?.len())
  8. }
  9. #[tokio::main]
  10. async fn main() {
  11. let urls: [&str; 4] = [
  12. "https://google.com",
  13. "https://httpbin.org/ip",
  14. "https://play.rust-lang.org/",
  15. "BAD_URL",
  16. ];
  17. let futures_iter = urls.into_iter().map(size_of_page);
  18. let results = future::join_all(futures_iter).await;
  19. let page_sizes_dict: HashMap<&str, Result<usize>> =
  20. urls.into_iter().zip(results.into_iter()).collect();
  21. println!("{:?}", page_sizes_dict);
  22. }

将此示例复制到准备好的 src/main.rs 文件中,并从该文件运行它。

  • 对于多个类型不相交的 Future,可以使用 std::future::join! 进行处理,但必须要确定在编译时 Future 的数量。目前,可在 futures crate 中使用该功能,但很快也会在 std::future 中正式发布。

  • The risk of join is that one of the futures may never resolve, this would cause your program to stall.

  • 还可以将 join_alljoin! 结合使用,并行处理所有对 http 服务的请求和数据库查询。尝试使用 futures::join!tokio::time::sleep 添加到 Future 中。这不是一个超时操作(其需要使用 select!,下一章会详细介绍),而是展示了 join! 的使用方式。