For loop with buffered channel
10,537
sync.WaitGroup
can be used here to wait for all goroutines and then closing the quotes
channel:
func getPrice(quotes chan<- string, onExit func()) {
go func() {
defer onExit()
req, _ := http.NewRequest("GET", "https://some/api", nil)
req.Header.Set("Accept", "application/json")
client := &http.Client{}
res, err := client.Do(req)
if err != nil {
panic(err) // should be handled properly
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
quotes <- string(body)
}()
}
func main() {
const max = 3
var wg sync.WaitGroup
quotes := make(chan string, max)
for i := 0; i < max; i++ {
wg.Add(1)
getPrice(quotes, func() { wg.Done() })
}
go func() {
defer close(quotes)
wg.Wait()
}()
for n := range quotes {
fmt.Printf("\n%s", n)
}
}
Author by
Ayub Malik
Updated on June 04, 2022Comments
-
Ayub Malik almost 2 years
I'm experimenting with Go channels and have an issue where the simple program below does not terminate.
Essentially I want to make some async HTTP get requests and then wait till they are all finished. I'm using a buffered channel but I'm not sure this is the idiomatic way.
func GetPrice(quotes chan string) { client := &http.Client{} req, _ := http.NewRequest("GET", "https://some/api", nil) req.Header.Set("Accept", "application/json") res, err := client.Do(req) if err != nil { panic(err) } defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) quotes <- string(body) } func main() { const max = 3 quotes := make(chan string, max) for i := 0; i < max; i++ { go GetPrice(quotes) } for n := range quotes { fmt.Printf("\n%s", n) } }
The program successfully prints 3(max) items
{"price":"1.00"} {"price":"2.00"} {"price":"3.00"}
but then blocks and never exits.
-
Ayub Malik over 6 yearsI'm going to go for this answer as it logically represents what I'm trying to do.
-
L_J over 5 yearsWhile this code may answer the question, providing information on how and why it solves the problem improves its long-term value.
-
jibeeeee over 3 yearsAccording to the documentation, higher-level synchronization is better done via channels and communication. It can be a solution for using chans