Asynchronous 管理错误时在管道中链接异步rest调用
在前面基于同步调用的基础上,我们如何在下面的场景中采用异步方法Asynchronous 管理错误时在管道中链接异步rest调用,asynchronous,f#,function-composition,Asynchronous,F#,Function Composition,在前面基于同步调用的基础上,我们如何在下面的场景中采用异步方法 let fetch1 (result: string) : Result<string, string> = try use request = WebRequest.Create("http://bing.com") :?> HttpWebRequest use response = request.GetResponse() use reader = ne
let fetch1 (result: string) : Result<string, string> =
try
use request = WebRequest.Create("http://bing.com") :?> HttpWebRequest
use response = request.GetResponse()
use reader = new StreamReader(response.GetResponseStream())
let html = reader.ReadToEnd()
Ok "success"
with
| :? WebException as e ->
Error "error with the url"
let fetch2 (result: string) : Result<string, string> =
try
use request = WebRequest.Create("http://google.com") :?> HttpWebRequest
use response = request.GetResponse()
use reader = new StreamReader(response.GetResponseStream())
let html = reader.ReadToEnd()
Ok "success"
with
| :? WebException as e ->
Error "error with the url"
let fetch3 (result: string) : Result<string, string> =
try
use request = WebRequest.Create("http://invalid.com") :?> HttpWebRequest
use response = request.GetResponse()
use reader = new StreamReader(response.GetResponseStream())
let html = reader.ReadToEnd()
Ok "success"
with
| :? WebException as e ->
Error "error with the url"
尝试
let chain = fetch1 >> Result.bind fetch2 >> Result.bind fetch3
match chain("") with
| Ok message -> Debug.WriteLine(message)
| Error error -> Debug.WriteLine(error)
let fetch1 (result: string) :Result<string, string> = async {
try
use! request = WebRequest.Create("http://bing.com") :?> HttpWebRequest
use response = request.GetResponse()
use reader = new StreamReader(response.GetResponseStream())
let html = reader.ReadToEnd()
Ok "success"
with
| :? WebException as e ->
Error "error with the url"
}
let fetch1(结果:字符串):结果=异步{
尝试
使用!request=WebRequest.Create(“http://bing.com“”:?>HttpWebRequest
使用response=request.GetResponse()
使用reader=newstreamreader(response.GetResponseStream())
设html=reader.ReadToEnd()
Ok“成功”
具有
|:?WebException作为e->
错误“url错误”
}
错误
此表达式被执行为具有类型“Result”,但此处具有类型“Async您应该解释您在此处实际尝试实现的异常处理机制。对于许多事情来说,只使用普通的F#内置异常将非常好地工作 您使用的是
Result.bind
,这是一种实现异常处理行为的方法,如果任何步骤抛出异常,整个计算都将失败。这就是你想要实现的吗?如果是这样的话,您可以依靠内置的F#异步支持进行异常处理,并让try。。在调用两个fetch
函数的异步计算中使用。一个简单的例子:
let fetch url = async {
use wc = new WebClient()
let! res = wc.AsyncDownloadString(System.Uri(url))
return res }
let fetchAllOrNothing = async {
try
let! goog = fetch "http://www.google.com"
let! bing = fetch "http://www.bing.com"
return Some(goog.Length, bing.Length)
with _ ->
return None }
如果您想调用所有的fetch函数,并且仅当所有函数都失败时才失败,那么您需要使用异常处理程序包装单个fetch
函数(就像您所做的那样),然后选择第一个结果。使用普通F#选项类型,可以使用Array.tryPick
:
let fetch url = async {
try
use wc = new WebClient()
let! res = wc.AsyncDownloadString(System.Uri(url))
return Some res
with _ ->
return None }
let fetchFirstOne = async {
let! all =
[ fetch "http://www.google.com"
fetch "http://www.bing.com" ] |> Async.Parallel
return Array.tryPick (fun x -> x) all }
如果您从F#开始,那么使用核心async
函数和选项就容易多了——一旦您熟悉了这些函数和选项,就有必要研究更复杂的方法。好吧,您将表达式更改为async
,但是您仍然坚持它的类型应该是Result
。难怪编译器感到困惑。您还不清楚什么?返回类型应该是什么,以及代码中的任何修复,我相信类似于的用法!请求
,感谢您对答案中代码的帮助。谢谢async
编译器告诉您,计算属于async
类型。您需要决定在Async
中应该包装什么类型,也就是说,您的异步计算应该生成什么类型。对不起,我不如您流利,我是初学者,我可以通过完整的代码图片很好地理解。您的意思是像这样Async
?我现在在正文中遇到了其他错误,这就是为什么我建议了一个完整的代码示例。对不起,我在这里感到困惑,抓取url就是一个示例,我的实际工作在每一个方面都有很多不同的东西,并且必须是不同的单个函数,你能用我的示例来调用3个函数fetch1、fetch2和fetch3吗,我不能在一个函数调用中概括所有函数。否则,我必须改变问题,放弃获取URL,并给出一个不同的示例。@Developer11只需在我的示例中用您的work1()
和work2()
函数替换fetch“oneUrl”
和fetch“anotherUrl”
,其余函数保持不变。链会发生什么情况,链将如何工作,我要把结果去掉吗?我还想看到下面带有匹配语句的链式调用的签名。根据我的“测试”,您不需要结果。bind
-我的示例是自包含的-它向您展示了编写异步计算的两种方法。好的,请向我展示编写链语句,然后我可以返回测试