github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/app/bconcurrent/or_done.go (about) 1 package bconcurrent 2 3 import "reflect" 4 5 // OrDone 任意channel完成后返回 6 func OrDone[T any](channels ...<-chan T) <-chan T { 7 switch len(channels) { 8 case 0: 9 // 返回已经关闭的channel 通知各个接受者关闭 10 c := make(chan T) 11 close(c) 12 return c 13 case 1: 14 return channels[0] 15 } 16 orDone := make(chan T, 1) 17 go func() { 18 defer close(orDone) 19 var cases []reflect.SelectCase 20 for _, channel := range channels { 21 cases = append(cases, reflect.SelectCase{ 22 Dir: reflect.SelectRecv, 23 Chan: reflect.ValueOf(channel), 24 }) 25 } 26 // 选择一个可用的 27 reflect.Select(cases) 28 }() 29 return orDone 30 }