Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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:?}");
}
This slide should take about 4 minutes.

Скопируйте этот пример в подготовленный src/main.rs и запустите его оттуда.

  • Для нескольких фьючерсов разных типов можно использовать std::future::join!, но нужно знать количество фьючерсов во время компиляции. Сейчас он находится в крейте futures, скоро будет стабилизирован в std::future.

  • Риск join в том, что один из фьючерсов может никогда не завершиться, и тогда программа зависнет.

  • Также можно комбинировать join_all с join!, например чтобы дождаться всех запросов к HTTP-сервису и запроса к базе данных. Попробуйте добавить tokio::time::sleep в фьючерс с использованием futures::join!. Это не таймаут (для него нужен select!, о котором пойдёт речь в следующей главе), но это демонстрирует join!.