输入 如果输入是由数组组成的数组。
let items = [|
[|"item1"; "item2"|]
[|"item3"; "item4"|]
[|"item5"; "item6"|]
[|"item7"; "item8"|]
[|"item9"; "item10"|]
[|"item11"; "item12"|]
|]
异步操作返回异步结果或错误。
let action (item: string) : Async<Result<string, string>> =
async {
return Ok (item + ":processed")
}
一次只处理一个子数组,并且并行处理
let result = items
|> Seq.map (Seq.map action >> Async.Parallel)
|> Async.Parallel // wrong? process root items sequentially
|> Async.RunSynchronously
期望:
a) 逐个并行处理每个子数组,然后逐个处理第二个子数组以此类推。(换句话说,对于根项进行顺序处理,对于子项进行并行处理)
b) 然后收集所有结果,并将它们合并为一个单维度的结果数组,同时保持顺序。
c) 最好使用 Array
、Seq
、List
、Async
等提供的内置方法,而不是任何自定义运算符(这应该是最后的选择)
d) 可选 - 如果在链中无法实现某些操作,则作为最后的选择,可以在最后将 result
子数组转换为单个数组并返回给调用方,如果这样做可以使代码更加简洁和精简,我更喜欢这种方法。
尝试2
let result2 = items
|> Seq.map (Seq.map action >> Async.Parallel)
|> Async.Parallel // wrong? is it processing root items sequentially
|> Async.RunSynchronously
|> Array.collect id
Array.iter (fun (item: Result<string, string>) ->
match item with
| Ok r -> Console.WriteLine(r)
| Error e -> Console.WriteLine(e)
) result2
Edit
let action (item: string) : Async<Result<string, string>> =
async {
return Ok (item + ":processed")
}
let items = [| "item1"; "item2"; "item3"; "item4"; "item5"; "item6"; "item7"; "item8"; "item9"; "item10"|]
let result = items
|> Seq.chunkBySize 2
|> Seq.map (Seq.map action >> Async.Parallel)
|> Seq.map Async.RunSynchronously
|> Seq.toArray
|> Array.collect id