F#的Async.Parallel
带有类型签名seq<Async<'a>> -> Async<'a list>
,它将采用一系列异步类型,准备它们并行运行,并输出一个Async。
我想知道是否有类似的Async.Sequential
具有相同的类型签名,但是依次运行每个项目的顺序?我觉得我必须遗漏一些明显的东西?
我想做类似以下的事情:
async {
let! results =
myItems
|> List.map myAsynchronousOperation
|> Async.Sequential
... do something with results
}
我不认为有一个内置,但编写自己的应该是微不足道的:
let sequential s = async {
let results = ResizeArray()
for a in s do
let! result = a
results.Add(result)
return List.ofSeq results
}
按顺序评估seq<Async<'a>>
中的项目并返回一个列表实际上只是序列中的foldBack
,您可以在async
将其列入列表之前评估cons
。虽然kvb的解决方案肯定有效,但您也可以使用像这样的Seq.foldBack
:
module Async =
let sequential s =
Seq.foldBack (fun cur acc -> async.Bind(cur, fun head ->
async.Bind(acc, fun tail -> async.Return(head :: tail)))) s (async.Return [])
如果有人愿意使用AsyncSeq库,那么以下内容将执行给定示例中所需的内容:
async {
let! results =
myItems
|> AsyncSeq.ofSeq
|> AsyncSeq.mapAsync myAsynchronousOperation
|> AsyncSeq.toListAsync
... do something with results
}
如果您还没有将AsyncSeq用于其他事情,可能会出现过度杀伤。