Day 7:第九週總結練習

學習目標

  • 綜合運用 async/await、spawn、HTTP、共享狀態
  • 完成一個非同步的實用工具

今日重點

本週回顧

  1. async fn 與 .await
  2. join! 並行
  3. tokio::spawn
  4. tokio::fs 非同步 I/O
  5. reqwest async HTTP
  6. select! / timeout
  7. tokio::sync::Mutex

綜合練習:並行抓取多個 API 並匯總

寫一支程式,用 tokio::spawn 並行抓取 5 個 todo,再收集顯示:

use serde::Deserialize;
use std::sync::Arc;
use tokio::sync::Mutex;

#[derive(Deserialize, Debug)]
struct Todo {
    id: u32,
    title: String,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let results = Arc::new(Mutex::new(Vec::new()));
    let mut handles = vec![];

    for id in 1..=5 {
        let results = Arc::clone(&results);
        handles.push(tokio::spawn(async move {
            let url = format!("https://jsonplaceholder.typicode.com/todos/{}", id);
            if let Ok(todo) = reqwest::get(&url).await?.json::<Todo>().await {
                results.lock().await.push(todo);
            }
        }));
    }
    for h in handles { h.await?; }

    for todo in results.lock().await.iter() {
        println!("{}: {}", todo.id, todo.title);
    }
    Ok(())
}

注意:upload 的 closure 若 ? 回傳需處理(這裡用 if let 或讓 spawn 回傳 Result)。練習兩種寫法。

挑戰

  • join! 版重寫(固定 5 個)。
  • 追蹤總耗時:並行應該比順序快將近 5 倍。

自我檢查

  • 能結合 spawn + Arc + async
  • 會並行抓取多個來源
  • 能安全地在 async 共享收集結果
  • 對 Rust 非同步有信心

週總結

你已能寫出高效的非同步程式與網路 client。 接下來進入錯誤處理的進階工具(anyhow / thiserror)。