英文:
GETing a list of urls in a async fashion in GO
问题
在我的GO应用程序中,我经常需要查询一个URL列表。由于GO是从底层开始异步的,所以这是使用这个功能的最佳场所。
解决这个问题的最佳方法是什么?我找到了一个博客提出的解决方案,但是当URL列表为空时它会失败。
谢谢!
英文:
I my GO application, I often need to query a list or urls. As GO is async from ground up, it is the perfect place to use this functionality.
What is the best way solve that? I found a blog proposing a solution but it fails with an empty list of urls.
Thanks!
答案1
得分: 2
我已经调整了你提供的博客链接中的代码,并使其对错误更具弹性。
下面的代码应该可以编译,并且应该处理边界情况,例如空的输入 urls
切片。
package main
import (
"fmt"
"net/http"
"os"
"time"
)
const timeout time.Duration = 3 * time.Second
var urls = []string{
"http://golang.org/",
"http://stackoverflow.com/",
"http://i.wanta.pony/", // 应该会出错
}
type httpResponse struct {
url string
response *http.Response
err error
}
func asyncHTTPGets(urls []string, ch chan *httpResponse) {
for _, url := range urls {
go func(url string) {
resp, err := http.Get(url)
ch <- &httpResponse{url, resp, err}
}(url)
}
}
func main() {
responseCount := 0
ch := make(chan *httpResponse)
go asyncHTTPGets(urls, ch)
for responseCount != len(urls) {
select {
case r := <-ch:
if r.err != nil {
fmt.Printf("获取 %s 时出错:%s\n", r.url, r.err)
} else {
fmt.Printf("%s 已获取\n", r.url)
}
responseCount++
case <-time.After(timeout):
os.Exit(1)
}
}
}
英文:
I've tweaked the code in the blog link you provided and made it slightly more resilient to error.
The code below should compile, and should handle boundary cases such as an empty input urls
slice.
package main
import (
"fmt"
"net/http"
"os"
"time"
)
const timeout time.Duration = 3 * time.Second
var urls = []string{
"http://golang.org/",
"http://stackoverflow.com/",
"http://i.wanta.pony/", // Should error
}
type httpResponse struct {
url string
response *http.Response
err error
}
func asyncHTTPGets(urls []string, ch chan *httpResponse) {
for _, url := range urls {
go func(url string) {
resp, err := http.Get(url)
ch <- &httpResponse{url, resp, err}
}(url)
}
}
func main() {
responseCount := 0
ch := make(chan *httpResponse)
go asyncHTTPGets(urls, ch)
for responseCount != len(urls) {
select {
case r := <-ch:
if r.err != nil {
fmt.Printf("Error %s fetching %s\n", r.err, r.url)
} else {
fmt.Printf("%s was fetched\n", r.url)
}
responseCount++
case <-time.After(timeout):
os.Exit(1)
}
}
}
答案2
得分: 0
由于您正在使用非缓冲通道,它将被阻塞,直到URL被处理完毕。
英文:
since you are using unbuffered channel, it's will be blocked until the url has been processed.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论