我们用Go 多个并发等待 Url请求 示例,改造
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
urls := []string{
"http://llever.com",
"http://llever.com/goreleaser-zh",
"http://llever.com/about/",
}
jsonResponses := make(chan int)
all := 0
for _, url := range urls {
all++ // 这个 ++,可以改成 原子添加,但也没那么必要
go getURL(url, jsonResponses)
}
index := 0
for response := range jsonResponses { // 等待 getURL 中 jsonResponses通道,返回
index++ // 这个 ++,则大可不必
if response != 0 { // 不为 0, 的正确项
fmt.Println(response)
break
} else {
fmt.Println(response) // 为0
}
}
go func(rest int) { // 后路
for i := 0; i < rest; i++ {
<-jsonResponses // 放飞剩下的
}
close(jsonResponses)
}(all - index)
fmt.Println("before done")
}
func getURL(url string, jsonResponses chan<- int) {
fmt.Println(url)
res, err := http.Get(url)
if err != nil {
jsonResponses <- 0 // 这时,并发的错误,就不能是直接退出处理了。
} else {
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
jsonResponses <- 0 // 要返回你认为的无效值
} else {
jsonResponses <- len(body)
fmt.Println("postsend")
}
}
}
注意,这里的程序,在打印完"before done"
之后就关闭了,后路有没有似乎不重要,但对通道的态度,要做好’省电’的意识
http://llever.com/about/
http://llever.com
http://llever.com/goreleaser-zh
postsend
22747
before done