return 在异步块中的位置,在 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 网络服务器,并且两个路径(正确和错误)return WebPart.
类型的对象
如果我尝试移动 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 块应该 return 一个 WebPart 对象,我认为用一个 return 包装它会更好。
编译器不同意:
[FS0750] This construct may only be used within computation expressions
我不明白为什么会这样。谁能给我解释一下?
那是因为您正在使用 let!
。
let!
在异步计算中创建一个断点,将代码分成两部分,第二部分作为延续传递(请参阅 this answer 了解其工作原理)。
你不能 return 整个事情作为一个单一的表达,因为它实际上不是一个单一的表达,它只是看起来像一个。实际上,您的函数在 let!
之后结束,一个完全独立的函数开始。
这是您的问题的简化版本:
let f = async {
return (let! x = doSomethingAsync)
}
这是否让您更好地了解出了什么问题?
我有以下代码:
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 网络服务器,并且两个路径(正确和错误)return WebPart.
类型的对象如果我尝试移动 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 块应该 return 一个 WebPart 对象,我认为用一个 return 包装它会更好。
编译器不同意:
[FS0750] This construct may only be used within computation expressions
我不明白为什么会这样。谁能给我解释一下?
那是因为您正在使用 let!
。
let!
在异步计算中创建一个断点,将代码分成两部分,第二部分作为延续传递(请参阅 this answer 了解其工作原理)。
你不能 return 整个事情作为一个单一的表达,因为它实际上不是一个单一的表达,它只是看起来像一个。实际上,您的函数在 let!
之后结束,一个完全独立的函数开始。
这是您的问题的简化版本:
let f = async {
return (let! x = doSomethingAsync)
}
这是否让您更好地了解出了什么问题?