有以下代码,使用它们会导致无限循环。来自通道的值是正确的,变量和的值也是正确的。所有goroutine最终都不会出错。
func responseHandler(w http.ResponseWriter, r *http.Request) {
var c = make(chan string)
for i := 0; i < 100; i++ {
url := fmt.Sprintf("someurl/page%v/etc", i)
go parse(url, i, c)
if i%5 == 0 {
time.Sleep(1000 * time.Millisecond)
}
}
for range c {
sum = append(sum, <-c)
}
fmt.Println("Exit from channel wait")
fmt.Fprintln(w, sum)
}
func parse(url string, num int, c chan string) {
response, err1 := http.Get(url)
if err1 != nil {
log.Fatal(err1)
}
defer response.Body.Close()
if response.StatusCode != 200 {
log.Fatalf("status code error: %d %s", response.StatusCode,
response.Status)
}
res, err := DecodeHTMLBody(response.Body, "windows-1251")
doc, err := goquery.NewDocumentFromReader(res)
if err != nil {
log.Fatal(err)
}
doc.Find(".b-advItem__content").Each(func(i int, s *goquery.Selection) {
title := strings.TrimSpace(s.Find(".someclass").Text())
price := strings.TrimSpace(s.Find(".someclass").Text())
formatPrice := parsePrice(price)
c <- fmt.Sprintf("output %d: %s:%s\n", i, title, formatPrice)
})
fmt.Printf("Channel %d - exit\n", num)
总和-全局[]字符串。
答案 0 :(得分:1)
仅当通道关闭时,通道上的public class SecondImplementation : FirstImplementation
{
public SecondImplementation(param1, param2, param3)
: base(param1, param2)
{
}
public override Bar Foo()
{
// do something with param1, param2 and param3, perhaps by calling base.Foo().
}
}
语句才会退出(好吧,想一想:range
将如何检测到没有其他数据要提取?),并且没有任何东西可以关闭通道通道中的代码。
答案 1 :(得分:-2)
func responseHandler(w http.ResponseWriter, r *http.Request) {
...
for range c {
sum = append(sum, <-c)
if len(aa) == 100 {
close(c)
}
fmt.Fprintln(w, sum)
}
func parse(...){
...
aa = append(aa, num)
}
添加此类检查可以使您正确退出循环