Join
عملیات پیوستن (join) منتظر میماند تا تمام مجموعهای از futureها آماده شوند و مجموعهای (collection) از نتایج آنها را برمیگرداند. این شبیه به Promise.all
در JavaScript یا 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 خواهید داشت. این در حال حاضر در جعبه (crate از نوعfutures
است که به زودی درstd::future
تثبیت میشود. -
خطر
join
این است که یکی از futureها ممکن است هرگز resolve نشود، این مسئله باعث میشود برنامه شما متوقف شود. -
همچنین میتوانید
join_all
را باjoin!
ترکیب کنید، بهعنوان مثال برای پیوستن (join!
) همه درخواستها به یک سرویس http و همچنین یک کوئری پایگاه داده سعی کنیدtokio::time::sleep
را با استفاده ازfutures::join!
به future اضافه کنید. این یک timeout نیست (که بهselect!
نیاز دارد و در فصل بعدی توضیح داده میشود) بلکهjoin!
را نشان میدهد.