F#:打破循环

时间:2015-04-01 12:54:46

标签: for-loop f#

我是编程新手,F#是我的第一语言。

我有一个URL列表,在首次访问时,会返回HTTP错误404或经历过网关超时。对于这些网址,我想尝试另外3次访问它们。在这3次尝试结束时,如果仍然抛出WebException错误,我将假设该URL不存在,我将其添加到包含所有无效URL的文本文件中。

这是我的代码:

let tryAccessingAgain (url: string) (numAttempts: int) =
    async {
        for attempt = 1 to numAttempts do
            try 
                let! html = fetchHtmlAsync url
                let name = getNameFromPage html

                let id = getIdFromUrl url

                let newTextFile = File.Create(htmlDirectory + "\\" + id.ToString("00000") + " " + name.TrimEnd([|' '|]) + ".html")
                use file = new StreamWriter(newTextFile) 
                file.Write(html) 
                file.Close()
            with
                :? System.Net.WebException -> File.AppendAllText("G:\User\Invalid URLs.txt", url + "\n")
        }

我在F#Interactive中测试了fetchHtmlAsync,getNameFromPage和getIdFromUrl。所有这些都很好。

如果我在不使用所有3次尝试的情况下成功下载URL的HTML内容,显然我想立即打破for循环。我的问题是:我怎么能这样做?

1 个答案:

答案 0 :(得分:4)

使用递归而不是循环:

let rec tryAccessingAgain (url: string) (numAttempts: int) =
    async {
        if numAttempts > 0 then
            try 
                let! html = fetchHtmlAsync url
                let name = getNameFromPage html

                let id = getIdFromUrl url

                let newTextFile = File.Create(htmlDirectory + "\\" + id.ToString("00000") + " " + name.TrimEnd([|' '|]) + ".html")
                use file = new StreamWriter(newTextFile) 
                file.Write(html) 
                file.Close()
            with
            | :? System.Net.WebException -> 
                File.AppendAllText("G:\User\Invalid URLs.txt", url + "\n")
                return! tryAccessingAgain url (numAttempts-1)
        }

请注意我无法测试它并且可能存在一些语法错误 - 对不起,如果

正如我们所做的那样 - 您可能想要重写无效网址的日志记录,如下所示:

let rec tryAccessingAgain (url: string) (numAttempts: int) =
    async {
        if numAttempts <= 0 then
            File.AppendAllText("G:\User\Invalid URLs.txt", url + "\n")
        else
            try 
                let! html = fetchHtmlAsync url
                let name = getNameFromPage html

                let id = getIdFromUrl url

                let newTextFile = File.Create(htmlDirectory + "\\" + id.ToString("00000") + " " + name.TrimEnd([|' '|]) + ".html")
                use file = new StreamWriter(newTextFile) 
                file.Write(html) 
                file.Close()
            with
            | :? System.Net.WebException -> 
                return! tryAccessingAgain url (numAttempts-1)
        }

这种方式只会在尝试完成后才会记录