Join
Операція об’єднання очікує, поки весь набір ф’ючерсів буде готовий, і повертає колекцію їхніх результатів. Це схоже на Promise.all
у JavaScript або asyncio.gather
у Python.
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!
.