Concurrent/Parallel 队列中的 Http 调用有节流
Concurrent/Parallel Http calls in a Queue with throttle
如果您有很多要调用的 URL,F# 中是否有任何具有某种限制的队列模式,比如在继续下一批之前一次调用 5 或 10 个。
let urls = [
"http://example.com/1",
"http://example.com/2",
"http://example.com/3",
....
"http://example.com/100"]
同时传递一个函数来调用
let getAsync (url:string) =
async {
let httpClient = new System.Net.Http.HttpClient()
let! response = httpClient.GetAsync(url) |> Async.AwaitTask
response.EnsureSuccessStatusCode () |> ignore
let! content = response.Content.ReadAsStringAsync() |> Async.AwaitTask
return content
}
然后收到所有 结果 和任何 错误 的列表,因为某些调用可能由于任何原因(例如 404 或 500 错误)而失败.
首先,让你的函数真正return错误信息而不是将其作为异常抛出:
let getAsync url : Result<_,_> =
async {
try
...
return (Ok content)
with ex ->
return (Error ex)
}
然后使用Async.Parallel
并行执行它们。这个函数接受一个 list<Async>
和 returns 一个 Async<list>
:
let allResults = urls |> List.map getAsync |> Async.Parallel
如果您有很多要调用的 URL,F# 中是否有任何具有某种限制的队列模式,比如在继续下一批之前一次调用 5 或 10 个。
let urls = [
"http://example.com/1",
"http://example.com/2",
"http://example.com/3",
....
"http://example.com/100"]
同时传递一个函数来调用
let getAsync (url:string) =
async {
let httpClient = new System.Net.Http.HttpClient()
let! response = httpClient.GetAsync(url) |> Async.AwaitTask
response.EnsureSuccessStatusCode () |> ignore
let! content = response.Content.ReadAsStringAsync() |> Async.AwaitTask
return content
}
然后收到所有 结果 和任何 错误 的列表,因为某些调用可能由于任何原因(例如 404 或 500 错误)而失败.
首先,让你的函数真正return错误信息而不是将其作为异常抛出:
let getAsync url : Result<_,_> =
async {
try
...
return (Ok content)
with ex ->
return (Error ex)
}
然后使用Async.Parallel
并行执行它们。这个函数接受一个 list<Async>
和 returns 一个 Async<list>
:
let allResults = urls |> List.map getAsync |> Async.Parallel