gpt4 book ai didi

async-await - F# 中的嵌套异步上下文

转载 作者:行者123 更新时间:2023-12-04 08:35:45 25 4
gpt4 key购买 nike

我必须通过网络多次调用 API。

let RestCall1 args = async{ Thread.Sleep (1000); return args}
let RestCall2 args = async{Thread.Sleep (1000); return args}
我知道 async{...} 上下文会影响性能,所以我试图尽量减少我创建的上下文数量。另外,管道很尴尬。
let nested4 args = async{ let! x = RestCall1 args; return args }
let nested7 args = async{ let! x = RestCall2 args; return args }

let outerAsync (args : string) =
async {
let args1 = args
|> nested1
|> nested2
|> nested3
let! args2 = nested4 args1
let args3 = args2
|> nested5
|> nested6
return nested7 args3
}
有没有办法在不使用 RunSynch 阻塞线程的情况下做到这一点(如下面的示例)?
let nested4 args = RestCall1 args |> Async.RunSynchronously
let nested7 args = RestCall2 args |> Async.RunSynchronously

let outerAsync (args : string) =
async {
return
args
|> nested1
|> nested2
|> nested3
|> nested4
|> nested5
|> nested6
|> nested7
}

最佳答案

您想避免 Async.Runsynchronously 是正确的,这会阻塞(请参阅 "Does Async.RunSynchronously block?" )。
正如 TheQuickBrownFox 所建议的,您需要一个提供 Async.map 和 Async.bind 的库。这里我使用了 FsToolkit.ErrorHandling:

  open System.Threading
open FsToolkit.ErrorHandling

let restCall1 args = async{ Thread.Sleep (1000); return args }
let restCall2 args = async{ Thread.Sleep (1000); return args }

let nested1 args = args
let nested2 args = args
let nested3 args = args
let nested4 args = restCall1 args
let nested5 args = args
let nested6 args = args
let nested7 args = restCall2 args

let outerAsync (args : string) : Async<string> =
args
|> nested1
|> nested2
|> nested3
|> nested4
|> Async.map nested5
|> Async.map nested6
|> Async.bind nested7
Async.map 采用了nested5 并从 (string -> string) 改变了它的签名。至 (Async<string> -> Async<string>) .它被称为 functor .
Async.bind 采用了nested7 并从 (string -> Async<string>) 改变了它的签名。至 (Async<string> -> Async<string>) .

关于async-await - F# 中的嵌套异步上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64811512/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com