2017-06-29 39 views
1

我從HTTP調用中獲得一些數據列表。然後我知道什麼值得到另一個HTTP電話。我想讓所有內容都是異步的。但我需要使用這個數據與Expecto'stestCaseAsync : string -> Async<unit> -> Test。所以,我的目標是得到像這樣的簽名Async<Item>[]F#使Async異步<Async<MyTpe> []>異步<MyType> []

所以,我想獲得一個列表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 
    } 

如果我運行它們在並行獲得:

// Async<Item[]> 
let getAsyncCalls = 
    async { 
     let! table = API.getTable() 
     // Item[] 
     let! items = 
      table.root 
      |> Array.map (fun x -> API.getItem x.id) 
     return item 
    } 

所以,這並不讓我Async<Item>[]。我不確定這是否可能。我想避免Async.RunSynchronouslyAPI.getTable調用,因爲這可能導致死鎖,對不對?它很可能會從一個緩存值(memoized)中調用,所以我不確定這會有所作爲。

我想我會繼續努力,除非別人比我更聰明:-)提前致謝!

回答

8

一般而言,您不能將Async<Async<T>[]>轉換爲Async<T>[]。問題是,即使獲得數組的長度,也需要異步執行某些操作,因此無法將數組「提升」到異步之外。如果你事先知道陣列的長度,那麼你可以做這個工作。

以下函數將Async<'T[]>轉換爲Async<'T>[],只要您給它數組的長度即可。如你所想,返回的異步需要以某種方式共享訪問一個頂級異步。做這個我能想到的最簡單的方法是使用任務。適應您的用例應該很容易:

相關問題