github.com/songzhibin97/gkit@v1.2.13/concurrent/or_done.go (about) 1 package concurrent 2 3 import "reflect" 4 5 // OrDone 任意channel完成后返回 6 func OrDone(channels ...<-chan interface{}) <-chan interface{} { 7 switch len(channels) { 8 case 0: 9 // 返回已经关闭的channel 通知各个接受者关闭 10 c := make(chan interface{}) 11 close(c) 12 return c 13 case 1: 14 return channels[0] 15 } 16 orDone := make(chan interface{}, 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 }