加入

會合作業會等待整個 Future 集合準備就緒,然後蒐集多個結果一次回傳。這類似於 JavaScript 中的 Promise.all 或 Python 中的 asyncio.gather

use anyhow::Result;
use futures::future;
use reqwest;
use std::collections::HashMap;

async fn size_of_page(url: &str) -> Result<usize> {
    let resp = reqwest::get(url).await?;
    Ok(resp.text().await?.len())
}

#[tokio::main]
async fn main() {
    let urls: [&str; 4] = [
        "https://google.com",
        "https://httpbin.org/ip",
        "https://play.rust-lang.org/",
        "BAD_URL",
    ];
    let futures_iter = urls.into_iter().map(size_of_page);
    let results = future::join_all(futures_iter).await;
    let page_sizes_dict: HashMap<&str, Result<usize>> =
        urls.into_iter().zip(results.into_iter()).collect();
    println!("{:?}", page_sizes_dict);
}

將這個範例複製到準備好的 src/main.rs,然後從中執行。

  • 若是多個不同型別的 Future,您可以使用 std::future::join!,但必須知道編譯時會有多少 Future。這目前位於 futures Crate 中,不久後就會在 std::future 中推出穩定版。

  • join 的風險是某個 Future 可能無法解決,導致程式停滯。

  • 舉例來說,您也可以併用 join_alljoin!,讓所有要求會合至 HTTP 服務和資料庫查詢。請嘗試使用 futures::join!,將 tokio::time::sleep 新增至 Future。這並非逾時 (逾時需要 select!,下一章會說明),而是示範 join!