У меня есть два goroutines независимо от данных, каждый отправляет их на канал. В моем главном goroutine я хотел бы потреблять каждый из этих выходов по мере их поступления, но не волнует порядок, в котором они входят. Каждый канал закроется, когда он исчерпает свой выход. Хотя оператор select является самым приятным синтаксисом для потребления входных данных независимо друг от друга, я не видел краткого пути для циклического перехода по каждому из них до тех пор, пока оба канала не будут закрыты.
for {
select {
case p, ok := <-mins:
if ok {
fmt.Println("Min:", p) //consume output
}
case p, ok := <-maxs:
if ok {
fmt.Println("Max:", p) //consume output
}
//default: //can't guarantee this won't happen while channels are open
// break //ideally I would leave the infinite loop
//only when both channels are done
}
}
лучшее, что я могу сделать, это следующее (просто набросанные, возможно, ошибки компиляции):
for {
minDone, maxDone := false, false
select {
case p, ok := <-mins:
if ok {
fmt.Println("Min:", p) //consume output
} else {
minDone = true
}
case p, ok := <-maxs:
if ok {
fmt.Println("Max:", p) //consume output
} else {
maxDone = true
}
}
if (minDone && maxDone) {break}
}
Но похоже, что это получится несостоятельным, если вы работаете с более чем двумя или тремя каналами. Единственным другим способом, который я знаю, является использование случая тайм-аута в операторе switch, который будет либо достаточно мал, чтобы рискнуть рано, либо ввести слишком много времени простоя в конечный цикл. Есть ли лучший способ проверить, что каналы находятся в выражении select?