输入如果输入是数组的数组形式。
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
编辑
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
最佳答案
let result = items |> Array.map ( Array.map action >> Async.Parallel)
|> Array.map Async.RunSynchronously
|> Array.collect id
编辑:请注意,在 Seq 上定义的大部分操作都可以在数组中找到,反之亦然。如果您最初有一个数组,则可以一直使用数组操作。
let items = [| "item1"; "item2"; "item3"; "item4"; "item5"; "item6"; "item7"; "item8"; "item9"; "item10"|]
let result = items
|> Array.chunkBySize 2
|> Array.map (Array.map action >> Async.Parallel >> Async.RunSynchronously)
|> Array.concat
关于arrays - 异步处理子数组并将结果缩减为单个数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49718231/