Rust中如何将变量传入并行异步HTTP GET请求并按Code存储结果
解决Rust并行异步请求中传递URL参数并保存文件的问题
不需要用不安全的全局变量,核心思路是在处理每个URL时先解析出code参数,再把code和请求结果一起返回,这样后续处理就能对应上每个请求的code,生成正确的保存路径。
步骤说明
- 添加
urlcrate作为依赖(用来解析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(()) }
关键细节说明
- URL解析:通过
url::Url解析字符串URL,利用query_pairs()遍历查询参数,精准提取code的取值;如果URL中没有code参数,默认使用"unknown"作为文件名。 - 结果绑定:在tokio异步任务中,将解析出的
code和请求得到的bytes一起返回,确保后续处理时每个数据块都能对应到正确的code。 - 异步文件操作:使用
tokio::fs提供的异步方法创建目录、写入文件,避免阻塞事件循环,契合Rust异步编程的最佳实践。
内容的提问来源于stack exchange,提问作者Gianandrea Siccardi
相关产品推荐
相关产品推荐

