簡體   English   中英

在異步塊中返回 position,在 F#

[英]return position in an async block, in F#

我有以下代碼:

let private SendOk (payload: 'a) : WebPart =
    payload |> Json.serialize |> OK >=> Writers.setMimeType "application/json"


let getBTCBalance (addresses: string list) : Async<WebPart> =
    async {
        try
            let! reply = blockExplorer.GetMultiAddressAsync addresses |> Async.AwaitTask
            return reply.Addresses |> Seq.map (fun x -> x.FinalBalance.GetBtc()) |> SendOk
        with
        | :? ArgumentNullException as ex -> return BAD_REQUEST    ex.Message
        | ex                             -> return INTERNAL_ERROR ex.Message
    }

它使用的是 Suave web 服務器,兩條路徑(正常和錯誤)都返回WebPart類型的 object 。

如果我嘗試移動 return 語句來包裝其他所有內容,我會得到以下代碼:

let getBTCBalance (addresses: string list) : Async<WebPart> =
    async {
        return ( 
            try
                let! reply = blockExplorer.GetMultiAddressAsync addresses |> Async.AwaitTask
                reply.Addresses |> Seq.map (fun x -> x.FinalBalance.GetBtc()) |> SendOk
            with
            | :? ArgumentNullException as ex -> BAD_REQUEST    ex.Message
            | ex                             -> INTERNAL_ERROR ex.Message
        )
    }

try/with 塊應該返回一個 WebPart object,我認為用一個返回包裹它會更好讀。

編譯器不同意:

[FS0750] 此構造只能在計算表達式中使用

我不明白為什么會這樣。 誰能給我解釋一下?

那是因為你正在使用let! .

let! 在異步計算中創建一個斷點,將代碼分成兩部分,第二部分作為延續傳遞(請參閱this answer了解其工作原理)。

您不能將整個內容作為單個表達式返回,因為實際上它不是單個表達式,它只是看起來像一個。 實際上,您的 function 在let! 一個完全獨立的 function 開始了。

這是您的問題的簡化版本:

let f = async {
  return (let! x = doSomethingAsync)
}

這能讓你更好地了解問題所在嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM