Jon*_*n49 1 f# asynchronous expecto
我从HTTP呼叫中获得了一些数据列表.然后我知道另一个HTTP电话会得到什么值.我希望一切都是异步的.但我需要使用这个数据Expecto的 testCaseAsync : string -> Async<unit> -> Test.所以,我的目标是获得这样的签名Async<Item>[]
所以,我想得到一份清单testCaseAsync.
所以,我基本上有这样的事情:
// Async<Async<Item>[]>
let getAsyncCalls =
async {
let! table = API.getTable ()
// Async<Item>[]
let items =
table.root
|> Array.map (fun x -> API.getItem x.id)
return item
}
Run Code Online (Sandbox Code Playgroud)
如果我并行运行它,我得到:
// Async<Item[]>
let getAsyncCalls =
async {
let! table = API.getTable ()
// Item[]
let! items =
table.root
|> Array.map (fun x -> API.getItem x.id)
return item
}
Run Code Online (Sandbox Code Playgroud)
所以,这不会让我这么做Async<Item>[].我不确定这是否可行.我想避免Async.RunSynchronously的API.getTable,因为该呼叫会导致死锁,对不对?它很可能是从缓存的值(memoized)中调用的,因此我不确定这会产生什么影响.
我想我会继续努力,除非别人比我更聪明:-)在此先感谢!
一般来说,你不能Async<Async<T>[]>变成Async<T>[].问题是,要获得数组的长度,您需要异步执行某些操作,因此无法在异步之外"提升"数组.如果您事先知道阵列的长度,那么您可以使其工作.
下面的功能将Async<'T[]>变成Async<'T>[]只要你给它的数组的长度.正如您所知,返回的asyncs需要以某种方式共享对一个顶级异步的访问权限.我能想到的最简单的方法是使用任务.根据您的使用情况调整它应该很容易:
let unwrapAsyncArray (asyncs:Async<'T[]>) len =
let task = asyncs |> Async.StartAsTask
Array.init len (fun i -> async {
let! res = Async.AwaitTask task
if res.Length <> len then failwith "Wrong length!"
return res.[i] }
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
94 次 |
| 最近记录: |