You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中如何将变量传入并行异步HTTP GET请求并按Code存储结果

解决Rust并行异步请求中传递URL参数并保存文件的问题

不需要用不安全的全局变量,核心思路是在处理每个URL时先解析出code参数,再把code和请求结果一起返回,这样后续处理就能对应上每个请求的code,生成正确的保存路径。

步骤说明

  • 添加url crate作为依赖(用来解析URL中的查询参数)
  • 解析每个URL的code值,和请求的bytes结果一起封装返回
  • 拿到code和bytes后,拼接目标路径,用异步IO写入文件

修改后的完整代码

use reqwest::Client;
use tokio_stream::StreamExt;
use url::Url;
use tokio::fs;

// 定义并行请求数量
const PARALLEL_REQUESTS: usize = 3;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut urls: Vec<&str> = vec![];
    urls.push("url1?code=AAA");
    urls.push("url2?code=BBB");
    urls.push("url3?code=CCC");

    let client = Client::new();
    // 替换为你的实际授权令牌
    let codice = "your_auth_token_here".to_string();

    let bodies = tokio_stream::iter(urls)
        .map(|url_str| {
            let client = client.clone();
            let codice = codice.clone();
            
            // 解析URL并提取code参数
            let url = Url::parse(url_str).unwrap();
            let code = url.query_pairs()
                .find(|(key, _)| key == "code")
                .map(|(_, val)| val.to_string())
                .unwrap_or_else(|| "unknown".to_string());

            tokio::spawn(async move {
                let resp = client.get(url_str)
                    .header("Authorization", codice)
                    .send()
                    .await?;
                
                // 同时返回code和请求到的字节数据
                Ok((code, resp.bytes().await?))
            })
        })
        .buffered(PARALLEL_REQUESTS);

    bodies
        .for_each(|result| async {
            match result {
                Ok(Ok((code, bytes))) => {
                    println!("Got {} bytes for code: {}", bytes.len(), code);
                    
                    // 拼接目标文件路径
                    let path = format!("data/esperimenti/{}.json", code);
                    // 确保目标目录存在
                    if let Err(e) = fs::create_dir_all("data/esperimenti").await {
                        eprintln!("Failed to create directory: {}", e);
                        return;
                    }
                    // 异步写入文件
                    if let Err(e) = fs::write(&path, bytes).await {
                        eprintln!("Failed to write file {}: {}", path, e);
                    } else {
                        println!("Successfully wrote file: {}", path);
                    }
                },
                Ok(Err(e)) => eprintln!("Request error: {}", e),
                Err(e) => eprintln!("Task join error: {}", e),
            }
        })
        .await;

    Ok(())
}

关键细节说明

  1. URL解析:通过url::Url解析字符串URL,利用query_pairs()遍历查询参数,精准提取code的取值;如果URL中没有code参数,默认使用"unknown"作为文件名。
  2. 结果绑定:在tokio异步任务中,将解析出的code和请求得到的bytes一起返回,确保后续处理时每个数据块都能对应到正确的code。
  3. 异步文件操作:使用tokio::fs提供的异步方法创建目录、写入文件,避免阻塞事件循环,契合Rust异步编程的最佳实践。

内容的提问来源于stack exchange,提问作者Gianandrea Siccardi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 17:23:14