我來自使用 async/await 的 C# 背景。我正在嘗試使用庫找到一種“不那么冗長”的編程方式。(特別是用于瀏覽器自動化的 Microsoft Playwright 庫)
let (~~) = Async.AwaitTask
let getLastPageNumber(page: IPage) =
let playwright = ~~Playwright.CreateAsync() |> Async.RunSynchronously
let browser = ~~playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions(Headless = false )) |> Async.RunSynchronously
~~page.GotoAsync("https://go.xero.com/BankRec/BankRec.aspx?accountID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx&page1") |> Async.RunSynchronously |> ignore
let lastPageLink = ~~page.QuerySelectorAsync("#mainPagerEnd") |> Async.RunSynchronously
if lastPageLink = null then
//this is the last page
1
else
let lastPageNumber = ~~lastPageLink.GetAttributeAsync("href") |> Async.RunSynchronously
lastPageNumber |> int
我使用別名 ~~ 為 Async.AwaitTask 縮短了一些東西,但似乎有很多代碼可以做一些在 C# 中更容易的事情。
uj5u.com熱心網友回復:
Async.RunSynchronously
應該只用作最后的手段,因為它阻塞了一個執行緒來執行計算,這違背了使用異步/任務的目的。
與 C# 的 async/await 等效的 F# 是使用 F# 的Async
型別和async
計算運算式。但是,如果您使用的是使用 .NETTask
型別的 .NET 庫,那么您可以使用具有計算運算式的TaskBuilder.fs庫task
。
然后你會寫這樣的函式:
open FSharp.Control.Tasks
let getLastPageNumber(page: IPage) = task {
let! playwright = Playwright.CreateAsync()
let! browser = playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions(Headless = false ))
let! _ = page.GotoAsync("https://go.xero.com/BankRec/BankRec.aspx?accountID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx&page1")
let! lastPageLink = page.QuerySelectorAsync("#mainPagerEnd")
if lastPageLink = null then
//this is the last page
return 1
else
let! lastPageNumber = lastPageLink.GetAttributeAsync("href")
return lastPageNumber |> int
}
在計算運算式(也稱為構建器)let!
內部用于等待任務。
請注意,此函式現在回傳Task<int>
而不是int
,因此呼叫者可能需要遵循類似的模式并進一步傳播任務。
您可以async
在此處閱讀有關在 F# 中使用的更多資訊。其中一些知識也可以應用于task
計算運算式。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/318805.html