【发布时间】:2020-07-29 08:04:24
【问题描述】:
我正在尝试构建一个简单的 API 爬虫,它会遍历分页内容并返回聚合结果。这是我第一次尝试编写递归函数:
namespace MyProject
open FSharp.Data
type MyJson = JsonProvider<"./Resources/Example.json">
module ApiClient =
let rec getAllPagesRec baseUrl (acc: MyJson.ItemList[]) (page: int) =
async {
let pageUrl = baseUrl + "&page=" + page.ToString()
let! response = Http.AsyncRequestString(pageUrl)
let content = MyJson.Parse(response)
let mergedArray = Array.concat [ content.ItemList; acc ]
if content.PageNumber < content.PageCount
then return! getAllPagesRec baseUrl mergedArray (page+1)
else return mergedArray
}
但是,我在Microsoft Docs 中读到这样的代码浪费了内存和处理器时间。所以我将我的函数重写为一个循环:
let getAllPagesLoop baseUrl =
async {
let mutable continueLoop = true
let mutable page = 1
let mutable acc = [||]
while continueLoop do
let pageUrl = baseUrl + "&page=" + page.ToString()
let! response = Http.AsyncRequestString(pageUrl)
let content = MyJson.Parse(response)
acc <- Array.concat [ content.ItemList; acc ]
if content.PageNumber < content.PageCount
then page <- page + 1
else continueLoop <- false
return acc
}
第二个函数看起来更像 C#-y 并且包含很多突变,这似乎与 F# 的哲学相矛盾。有没有其他方法可以“优化”第一个功能?也许使用yield/yield! 关键字?还是两个功能都足够好?
【问题讨论】:
标签: f#