我尝试使用Rust的时雄和reqwest crates重新实现以下Python代码。
#!/usr/bin/env python3
import asyncio
import httpx
import time
async def async_req(url, client):
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.54",
"Cookie": ""
}
response = await client.get(url, headers=headers, timeout=180)
print(response.status_code)
print(response.text)
async def main():
urls = ["http://localhost:5000/hello", "http://localhost:5000/world"]
start = time.time()
async with httpx.AsyncClient() as client:
tasks = [async_req(url, client) for url in urls]
await asyncio.gather(*tasks)
print(time.time()-start)
if __name__ == "__main__":
asyncio.run(main())
在Rust中实现的代码如下:
async fn async_req(
url: &str,
client: reqwest::Client,
) -> Result<reqwest::Response, Box<dyn std::error::Error>> {
let response = client
.get(url)
.timeout(std::time::Duration::from_secs(180))
.send()
.await?;
Ok(response)
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let urls = vec![
"http://localhost:5000/hello",
"http://localhost:5000/world",
];
let mut handles = vec![];
let client = reqwest::Client::new();
for url in urls {
let handle = {
let client = client.clone();
async move { async_req(url, client).await }
};
handles.push(handle);
}
let mut responses = vec![];
for handle in handles {
responses.push(handle.await?);
}
for response in responses {
println!("{}", response.text().await?);
}
Ok(())
}
但是看起来这个程序并没有像在Python中那样发出异步请求。
我还没有找到一个不产生错误的解决方案。Cargo.toml的配置如下,我使用的Rust编译器版本是1.72.1(d5 c2 e9 c34,2023-09-13)。
[package]
name = "reqwest_async_demo"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
reqwest = { version = "^0.11" }
tokio = { version = "^1", features = [ "full" ] }
1条答案
按热度按时间zvms9eto1#
您可以使用
tokio::try_join!
或futures::future::join_all
来并发运行期货。这些方法返回一个future,当所有future都完成时,future也完成,并生成所有结果的集合。这类似于Python中asyncio.gather
的行为。首先,将
futures
crate添加到Cargo.toml
:主要功能:
tokio::spawn
用于在新任务中并发地启动每个future,然后futures::future::join_all
用于等待所有任务。join_all
函数返回一个future,该future解析为传递给它的future结果的Vec
。