1// слить все каналы в один; если хотя бы один закрылся — закрыть остальные2func combine(streams ...chan int) <-chan int {3 out := make(chan int, len(streams))4 var grp sync.WaitGroup5 var once sync.Once6 7 ctx, cancel := context.WithCancel(context.Background())8 9 for _, s := range streams {10 grp.Add(1)11 go func(s chan int) {12 defer grp.Done()13 14 for {15 select {16 case v, ok := <-s:17 if !ok {18 once.Do(cancel)19 return20 }21 22 select {23 case out <- v:24 case <-ctx.Done():25 close(s)26 return27 }28 29 case <-ctx.Done():30 close(s)31 return32 }33 }34 }(s)35 }36 37 go func() {38 grp.Wait()39 close(out)40 }()41 42 return out43}