Join
Операция join ждёт, пока все фьючерсы из набора не будут готовы, и возвращает коллекцию их результатов. Это похоже на Promise.all в JavaScript или asyncio.gather в Python.
// Copyright 2024 Google LLC
// SPDX-License-Identifier: Apache-2.0
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 и запустите его оттуда.
-
Для нескольких фьючерсов разных типов можно использовать
std::future::join!, но нужно знать количество фьючерсов во время компиляции. Сейчас он находится в крейтеfutures, скоро будет стабилизирован вstd::future. -
Риск
joinв том, что один из фьючерсов может никогда не завершиться, и тогда программа зависнет. -
Также можно комбинировать
join_allсjoin!, например чтобы дождаться всех запросов к HTTP-сервису и запроса к базе данных. Попробуйте добавитьtokio::time::sleepв фьючерс с использованиемfutures::join!. Это не таймаут (для него нуженselect!, о котором пойдёт речь в следующей главе), но это демонстрируетjoin!.