非同期の例 は便利ですが、RustとTokioに慣れていないため、ベクターからのURLを使用して、一度にN個のリクエストを実行する方法を見つけるのに苦労しています。各URLの応答HTMLのイテレータを文字列として作成します。
これはどのように行うことができますか?
Reqwest 0.10現在:
use futures::{stream, StreamExt}; // 0.3.1
use reqwest::Client; // 0.10.0
use tokio; // 0.2.4, features = ["macros"]
const PARALLEL_REQUESTS: usize = 2;
#[tokio::main]
async fn main() {
let client = Client::new();
let urls = vec!["https://api.ipify.org", "https://api.ipify.org"];
let bodies = stream::iter(urls)
.map(|url| {
let client = &client;
async move {
let resp = client.get(url).send().await?;
resp.bytes().await
}
})
.buffer_unordered(PARALLEL_REQUESTS);
bodies
.for_each(|b| {
async {
match b {
Ok(b) => println!("Got {} bytes", b.len()),
Err(e) => eprintln!("Got an error: {}", e),
}
}
})
.await;
}
stream::iter(urls)
文字列のコレクションを取得し、それを Stream
に変換します。
.map(|url| {
ストリーム内のすべての要素で非同期関数を実行し、要素を新しいタイプに変換します。
let client = &client; async move {
Client
への明示的な参照を取得し、その参照(元のClient
ではない)を匿名の非同期ブロックに移動します。
let resp = client.get(url).send().await?;
Client
の接続プールを使用して非同期GET要求を開始し、要求を待ちます。
resp.bytes().await
応答のバイトを要求して待ちます。
.buffer_unordered(N);
先物のストリームをそれらの先物の値のストリームに変換し、先物を並行して実行します。
bodies .for_each(|b| { async { match b { Ok(b) => println!("Got {} bytes", b.len()), Err(e) => eprintln!("Got an error: {}", e), } } }) .await;
ストリームを単一のfutureに変換し直し、途中で受信したデータの量を出力してから、futureが完了するのを待ちます。
参照: