【发布时间】:2019-02-07 01:58:57
【问题描述】:
我对@987654327@很陌生。所以,请给我一把剑(如果可能的话)。
我试图通过学习教程here从网络获取数据
现在,教程一切顺利,但我想检查边缘情况和错误处理(只是为了彻底了解我对语言的新学习,不想成为知识不成熟的人) .
这是我的go-playground code。
在询问之前,我查看了很多参考资料,例如:
还有一些,但我想不通。
如果你不想去操场,这里是代码(原因未知):
// MakeRequest : Makes requests concurrently
func MakeRequest(url string, ch chan<- string, wg *sync.WaitGroup) {
start := time.Now()
resp, err := http.Get(url)
defer func() {
resp.Body.Close()
wg.Done()
if r := recover(); r != nil {
fmt.Println("Recovered in f", r)
}
}()
if err != nil {
fmt.Println(err)
panic(err)
}
secs := time.Since(start).Seconds()
body, _ := ioutil.ReadAll(resp.Body)
ch <- fmt.Sprintf("%.2f elapsed with response length: %d %s", secs, len(body), url)
}
func main() {
var wg sync.WaitGroup
output := []string{
"https://www.facebook.com",
"",
}
start := time.Now()
ch := make(chan string)
for _, url := range output {
wg.Add(1)
go MakeRequest(url, ch, &wg)
}
for range output {
fmt.Println(<-ch)
}
fmt.Printf("%.2fs elapsed\n", time.Since(start).Seconds())
}
更新
我将代码更改为(比方说)像这样(go-playground here)处理 goroutine 中的错误:
func MakeRequest(url string, ch chan<- string, wg *sync.WaitGroup) {
start := time.Now()
resp, err := http.Get(url)
if err == nil {
secs := time.Since(start).Seconds()
body, _ := ioutil.ReadAll(resp.Body)
ch <- fmt.Sprintf("%.2f elapsed with response length: %d %s", secs, len(body), url)
// fmt.Println(err)
// panic(err)
}
defer wg.Done()
}
更新 2:
在得到答复后,我将代码更改为此并成功消除了chan 死锁,但是现在我需要在main 中处理这个问题:
func MakeRequest(url string, ch chan<- string, wg *sync.WaitGroup) {
defer wg.Done()
start := time.Now()
resp, err := http.Get(url)
if err == nil {
secs := time.Since(start).Seconds()
body, _ := ioutil.ReadAll(resp.Body)
ch <- fmt.Sprintf("%.2f elapsed with response length: %d %s", secs, len(body), url)
// fmt.Println(err)
// panic(err)
}
// defer resp.Body.Close()
ch <- fmt.Sprintf("")
}
难道没有更优雅的方式来处理这个问题吗?
但现在我陷入了僵局。
感谢和问候。
临时工
(一个 golang 菜鸟)
【问题讨论】:
-
您要解决的具体问题是什么?
-
恐慌也不例外,它们旨在表明程序出现问题并崩溃。
-
如果 err 不是 nil,resp 是。由于 nil 指针取消引用,您的延迟函数将 再次 恐慌。
-
对不起,大家对我的跛脚,我只想在出现错误的任何其他情况下安全退出 goroutine,仅此而已:)
-
如果没有错误,您的 Update 2 代码将死锁!成功后,它会尝试发送两次消息。操场总是失败,这就是它在那里工作正常的原因。
标签: go