package main import ( "context" "errors" "fmt" log "github.com/sirupsen/logrus" "io/ioutil" "net/http" "sync" ) const ( url = "https://api.binance.com/api/v3/avgPrice?symbol=ETHBTC" ) func createOrder(orderID int, ch chan<- string, ce chan<- error, wg *sync.WaitGroup){ defer wg.Done() if orderID == 4{ log.Println("invalid order") ce <- errors.New("invalid order number") return } resp, err := http.Get("https://api.binance.com/api/v3/avgPrice?symbol=ETHBTC") if err != nil { log.Println("err handle it", orderID) ce <- err return } defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) if err != nil { log.Println("err handle it") ce <- err return } ch <- string(b) } func main() { ctx := context.Background() ctx, cancel := context.WithCancel(ctx) orders := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} log.WithFields(log.Fields{ "orders": orders, }).Info("creating orders") var wg sync.WaitGroup ch := make(chan string) errors := make(chan error) var responses []string for _, orderID := range orders { wg.Add(1) go createOrder(orderID, ch, errors, &wg) } // close the channel in the background go func() { wg.Wait() close(ch) close(errors) }() for range orders { select { case response := <-ch: fmt.Println("received", response) responses = append(responses, response) case err := <-errors: fmt.Println("received", err) cancel() break } } //// read from channel as they come in until its closed //for res := range ch { // responses = append(responses, res) //} for _, r := range responses{ log.WithFields(log.Fields{ "response": r, }).Info("received response") } }