2017-06-29 5 views
1

Ich bekomme eine Liste von Daten von einem HTTP Aufruf. Ich weiß dann, welche Werte für einen anderen HTTP Anruf erhalten. Ich möchte alles asynchron haben. Aber ich muss diese Daten mit Expecto'stestCaseAsync : string -> Async<unit> -> Test verwenden. Also, mein Ziel ist es, eine Signatur wie folgt zu bekommenF # Async machen <Async<MyTpe> []> zu Async <MyType> []

So würde ich gerne eine Liste von testCaseAsync bekommen.

Also, ich habe im Grunde so etwas wie dieses:

// 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 
    } 

Wenn ich sie parallel laufen erhalte ich:

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

So, das mich nicht Async<Item>[] bekommt. Ich bin mir nicht sicher, ob das möglich ist. Ich möchte Async.RunSynchronously für den API.getTable Aufruf vermeiden, da das zu Deadlocks führen kann, richtig? Es wird höchstwahrscheinlich von einem zwischengespeicherten Wert (memoized) aufgerufen werden, also bin ich nicht sicher, dass das einen Unterschied machen wird.

Ich denke, ich werde weiter daran arbeiten, wenn jemand anderes ist schlauer als ich :-) Vielen Dank im Voraus!

Antwort

8

Im Allgemeinen können Sie Async<Async<T>[]> nicht in Async<T>[] umwandeln. Das Problem besteht darin, dass Sie, um die Länge des Arrays zu erhalten, einige Operationen asynchron ausführen müssen, sodass es keine Möglichkeit gibt, das Array außerhalb des Async zu "heben". Wenn Sie die Länge des Arrays im Voraus kannten, können Sie dies durchführen.

Die folgende Funktion wandelt Async<'T[]> in Async<'T>[] um, sofern Sie die Länge des Arrays angeben. Wie Sie herausgefunden haben, müssen die zurückgegebenen asyncs irgendwie den Zugriff auf das eine async der obersten Ebene freigeben. Der einfachste Weg, dies zu tun, ist die Verwendung einer Aufgabe. Die Anpassung für Ihren Anwendungsfall sollte einfach sein:

Verwandte Themen